将镶木地板读入熊猫时如何解决内存问题

时间:2019-09-24 16:01:34

标签: python pandas amazon-s3 parquet pyarrow

我正在将文件从S3读取到Pandas数据框中:文件是已分区的实木复合地板。我将在Lambda中使用它,因此我需要对内存非常保守。当我运行以下语句时,我的内存不足:

pq.ParquetDataset(f's3://{path}', filesystem=s3).read_pandas().to_pandas()

但是,如果我运行以下命令,那很好:

pq.ParquetDataset(f's3://{path}', filesystem=s3)

然后如果添加,它将再次中断:

pq.ParquetDataset(f's3://{path}', filesystem=s3).read_pandas()

未压缩的数据大小为500 MB,我有3 GB的RAM。是否有更有效的内存方式将一系列实木复合地板拉入Pandas Dataframe?

我尝试过的其他事情:

这不起作用,因为如果包含太长的字符串,它将中断:

for obj in bucket.objects.filter(Prefix=f'{prefix}'):
    obj = s3_resource.Object(buckey,obj.key)
    obj.download_fileobj(buffer)
    df = pd.read_parquet(buffer)

另一种无效的尝试:

def memory_optimized_pull(datekey, filter_column, filter_column_value):
    s3_resource = boto3.resource('s3')
    bucket_name = 'bn'
    bucket = s3_resource.Bucket(name=bucket_name)
    df_list = []
    for obj in bucket.objects.filter(Prefix=...):
        f = s3.open(f'{bucket_name}/{obj.key}')
        df = pq.read_table(f).to_pandas()
        df = df[df[filter_column] == filter_column_value]
        df_list.append(df)
    return pd.concat(df_list, ignore_index=True, sort=False)

1 个答案:

答案 0 :(得分:0)

pq.ParquetDataset(f's3://{path}', filesystem=s3)没用完内存的原因是它没有加载任何东西。它只是封装了如何读取数据集的详细信息,但实际上直到调用read时才做任何事情。

当您说未压缩的数据大小为500 MB时,是指一旦加载到内存中?如果这是s3中的文件大小,则可能是使用snappy压缩的(pandas to_parquet默认)。

通常,镶木地板用于更大的数据集,而AWS Lambda并不是重载ETL作业的最佳选择。