从 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')