首页 > 解决方案 > 选择子集后将其转换为熊猫时,Dask 数据帧内存不足

问题描述

所以我有一个包含160M记录和240列的镶木地板文件。所以我使用 dask 使用 EMR CLuster 在 python 中加载它m5.12xlarge

import dask.dataframe as dd

df = dd.read_parquet(file)

现在我想要其中一列的值计数和标准化值计数:

count = df.a.value_counts()
percent = df.a.value_counts(normalize = True)
a_count = dd.concat([count,percent], axis=1, keys=['counts', '%'])

出去:

Dask DataFrame Structure:
    counts  %
npartitions=1       
    int64   float64
    ...     ...
Dask Name: concat, 489 tasks

请注意,我有1 npartitions总和489 task

现在我正在尝试将其转换为 pandas df。只需几秒钟即可执行和使用1.5 GB内存。

a_count = a_count.compute()

现在,从其中一列中,我想要所有具有空值的记录,然后像我之前所做的一样执行值计数。

empty_b = df[df['b'].isna()]

count = empty_b.a.value_counts()
percent = empty_b.a.value_counts(normalize = True)
empty_b = dd.concat([count,percent], axis=1, keys=['counts', '%'])
empty_b 

出去:

Dask DataFrame Structure:
    counts  %
npartitions=1       
    int64   float64
    ...     ...
Dask Name: concat, 828 tasks

1 npartition其中有一个总和828 task

现在我正在尝试通过计算将其转换为 pandas 数据帧,并且在使用170 GB.

empty_b  = empty_b.compute()

有人可以解释这里出了什么问题吗,我正在做同样的事情,并且也在更大的一个子集上,但我的笔记本仍然内存不足并且无法执行。

标签: pythonpython-3.xpandasdataframedask

解决方案


我有一个包含 160M 记录和 240 列的镶木地板文件

最好将此数据拆分为多个 Parquet 文件

我正在使用 dask 使用 EMR Cluster m5.12xlarge 在 python 中加载它

这种实例类型有 48 个 CPU。这是多节点实例还是单节点?

请注意,我总共有 1 个 npartitions 和 489 个任务。

您可能在单个内核上运行所有这些计算。尝试将 DataFrame 重新分区为至少 48 个分区,这样您就可以在强大的机器上利用并行性。

现在我正在尝试将其转换为熊猫数据框

您通常不希望将 Dask DataFrames 转换为 Pandas DataFrames,除非您已显着减少数据行数。一旦转换为 Pandas,您将失去 Dask 的并行性可以提供的所有好处。

在此示例中,您似乎正在将单个 Parquet 文件读入具有一个分区的 Dask DataFrame,然后将其转换回 Pandas。您可能需要考虑将 Dask DataFrame 分解为多个分区(并通过 Dask 运行计算)或直接将文件读入 Pandas DataFrame。


推荐阅读