我正在将文件从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)
答案 0 :(得分:0)
pq.ParquetDataset(f's3://{path}', filesystem=s3)
没用完内存的原因是它没有加载任何东西。它只是封装了如何读取数据集的详细信息,但实际上直到调用read时才做任何事情。
当您说未压缩的数据大小为500 MB时,是指一旦加载到内存中?如果这是s3中的文件大小,则可能是使用snappy压缩的(pandas to_parquet
默认)。
通常,镶木地板用于更大的数据集,而AWS Lambda并不是重载ETL作业的最佳选择。