内存不足:将大型数据从 Amazon Redshift 传输到 Pandas



>我在Amazon-Redishift中有一个大型数据块(大约10M行(,我将在Pandas数据帧中获取并将数据存储在pickle文件中。但是,由于数据的大小,由于明显的原因,它显示"内存不足"异常。我尝试了很多其他的东西,比如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( 通过添加order by [column] limit [number] offset 0并合理增加限制数来查找表中的行数和可以拉取的表的最大块

2( 添加一个循环,该循环将产生具有您发现的限制并增加偏移量的 SQL,即如果您可以拉取 10k 行,您的语句将是:

... limit 10000 offset 0;
... limit 10000 offset 10000;
... limit 10000 offset 20000;

直到达到表行数

3( 在同一循环中,将每个新获得的行集附加到数据帧。

p.s. 假设您不会在客户端遇到任何问题,我无法保证,因为您在可能是更高等级硬件的集群上遇到此类问题,这将起作用。为了避免这个问题,您只需在每次迭代时写入一个新文件,而不是追加。

此外,整个方法可能不正确。您最好将表卸载到 S3,这非常快,因为数据是从每个节点独立复制的,然后对 S3 上的平面文件执行任何需要的操作,以将其转换为所需的最终格式。

如果您使用 pickle 将数据传输到其他地方,我会重复 AlexYes 答案中的建议 - 只需使用 S3。

但是,如果您希望能够在本地处理数据,则必须将自己限制在不需要所有数据才能工作的算法上。 在这种情况下,我会建议使用HDF5或Parquet用于数据存储,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')

最新更新