从 Amazon Redshift 到 Pandas 的 Memory:Transferring 个大数据
Out of Memory:Transferring Large Data from Amazon Redshift to Pandas
我在 Amazon-Redishift 中有一个大数据块(大约 1000 万行),我要在 Pandas 数据框中获取该数据并将数据存储在 pickle 文件中。但是,由于明显的原因,它显示 "Out of Memory" 异常,因为数据的大小。我尝试了很多其他的东西,比如 sqlalchemy,但是,无法解决问题。任何人都可以提出更好的方法或代码来完成它。
我当前的(简单的)代码片段如下:
import psycopg2
import pandas as pd
import numpy as np
cnxn = psycopg2.connect(dbname=<mydatabase>, host='my_redshift_Server_Name', port='5439', user=<username>, password=<pwd>)
sql = "Select * from mydatabase.mytable"
df = pd.read_sql(sql, cnxn, columns=1)
pd.to_pickle(df, 'Base_Data.pkl')
print(df.head(50))
cnxn.close()
print(df.head(50))
1) 找到table中的行数和table中可以通过添加order by [column] limit [number] offset 0
并合理增加限制数来拉取的最大块
2) 添加一个循环,该循环将生成 sql 以及您找到的限制和增加的偏移量,即如果您可以提取 10k 行,您的语句将是:
... limit 10000 offset 0;
... limit 10000 offset 10000;
... limit 10000 offset 20000;
直到达到 table 行数
3) 在同一个循环中,将每个新获得的行集附加到数据框。
p.s。假设您不会 运行 在客户端遇到 memory/disk 的任何问题,这将起作用,我不能保证,因为您在可能是更高级别硬件的集群上遇到这样的问题。为避免此问题,您只需在每次迭代时写入一个新文件而不是追加。
此外,整个方法可能不正确。您最好将 table 卸载到 S3,这非常快,因为数据是从每个节点独立复制的,然后对 S3 上的平面文件执行任何需要的操作,将其转换为您需要的最终格式。
如果您使用 pickle 只是将数据传输到其他地方,我会重复 AlexYes 的回答中的建议 - 只需使用 S3。
但是,如果您希望能够在本地处理数据,则必须将自己限制在不需要所有数据都能工作的算法上。
在这种情况下,我建议对数据处理使用 HDF5 or Parquet for data storage and Dask 之类的方法,因为它不需要所有数据都驻留在内存中——它可以分块并行工作。您可以使用以下代码从 Redshift 迁移数据:
from dask import dataframe as dd
d = dd.read_sql_table(my_table, my_db_url, index_col=my_table_index_col)
d.to_hdf('Base_Data.hd5', key='data')
我在 Amazon-Redishift 中有一个大数据块(大约 1000 万行),我要在 Pandas 数据框中获取该数据并将数据存储在 pickle 文件中。但是,由于明显的原因,它显示 "Out of Memory" 异常,因为数据的大小。我尝试了很多其他的东西,比如 sqlalchemy,但是,无法解决问题。任何人都可以提出更好的方法或代码来完成它。
我当前的(简单的)代码片段如下:
import psycopg2
import pandas as pd
import numpy as np
cnxn = psycopg2.connect(dbname=<mydatabase>, host='my_redshift_Server_Name', port='5439', user=<username>, password=<pwd>)
sql = "Select * from mydatabase.mytable"
df = pd.read_sql(sql, cnxn, columns=1)
pd.to_pickle(df, 'Base_Data.pkl')
print(df.head(50))
cnxn.close()
print(df.head(50))
1) 找到table中的行数和table中可以通过添加order by [column] limit [number] offset 0
并合理增加限制数来拉取的最大块
2) 添加一个循环,该循环将生成 sql 以及您找到的限制和增加的偏移量,即如果您可以提取 10k 行,您的语句将是:
... limit 10000 offset 0;
... limit 10000 offset 10000;
... limit 10000 offset 20000;
直到达到 table 行数
3) 在同一个循环中,将每个新获得的行集附加到数据框。
p.s。假设您不会 运行 在客户端遇到 memory/disk 的任何问题,这将起作用,我不能保证,因为您在可能是更高级别硬件的集群上遇到这样的问题。为避免此问题,您只需在每次迭代时写入一个新文件而不是追加。
此外,整个方法可能不正确。您最好将 table 卸载到 S3,这非常快,因为数据是从每个节点独立复制的,然后对 S3 上的平面文件执行任何需要的操作,将其转换为您需要的最终格式。
如果您使用 pickle 只是将数据传输到其他地方,我会重复 AlexYes 的回答中的建议 - 只需使用 S3。
但是,如果您希望能够在本地处理数据,则必须将自己限制在不需要所有数据都能工作的算法上。 在这种情况下,我建议对数据处理使用 HDF5 or Parquet for data storage and Dask 之类的方法,因为它不需要所有数据都驻留在内存中——它可以分块并行工作。您可以使用以下代码从 Redshift 迁移数据:
from dask import dataframe as dd
d = dd.read_sql_table(my_table, my_db_url, index_col=my_table_index_col)
d.to_hdf('Base_Data.hd5', key='data')