随机访问一行 Dask 数据帧需要很长时间

问题描述 投票:0回答:4

我有一个包含 1 亿行数据的 Dask 数据框。

我试图在不加载整个数据帧的情况下迭代这个数据帧 到内存。

对于实验,尝试访问索引行等于 1.

%time dask_df.loc[1].compute()

耗时高达 8.88 秒(Wall time)

为什么要花这么长时间?

我该怎么做才能让它更快?

提前致谢。

根据要求,这是代码。 它只是读取 1 亿行数据并尝试访问一行。

`dask_df = dd.read_parquet("/content/drive/MyDrive/AffinityScore_STAGING/staging_affinity_block1.gzip", chunksize=10000000)`

Dask DataFrame 结构: avg_user_prod_aff_score internalItemID internalUserID npartitions=1
float32 int16 int32

len(dask_df)

100,000,000

%time dask_df.loc[1].compute()

只有 3 列数据类型为 float32、int16 和 int32。

dataframe 的索引从 0 开始

写的时间其实很好,2分钟左右。

我一定是在这里做错了什么。

python dask dask-dataframe
4个回答
1
投票

与 pandas 类似,

dask_df[1]
实际上会引用一列,而不是一行。因此,如果您有一个名为
1
的列,那么您只是从整个框架中加载一个列。您不能按位置访问行 -
df.iloc
仅支持沿第二(列)轴的索引。如果您的索引中有值
1
,您可以使用
df.loc
选择它,例如:

df.loc[1].compute()

有关索引的dask.dataframe 文档有关更多信息和示例。


1
投票

在未索引的数据帧上执行

.loc
时,Dask 将需要解压缩整个文件。由于每个分区都有自己的索引,
.loc[N]
将检查每个分区的
N
,请参阅this answer

解决这个问题的一种方法是支付一次生成唯一索引并保存索引的 parquet 文件的成本。这样

.loc[N]
只会从包含行
N
.

的特定分区(或行组)加载信息

0
投票

使用示例方法。

您没有掌握 dask 和 pandas 之间的必要区别之一……分布式索引。这意味着必须使用 loc 至少检查所有文件上的元数据,并且您还可能遇到出现在多个(可能是索引未排序的)分区中的索引。

如果您需要随机数据,请使用示例。 Loc 用于其他用途,与 pandas 的 loc 不同。


-1
投票

看起来 Dask 在尝试时存在性能问题 访问 1000 万行。访问前 10 行需要 2.28 秒。

1 亿行,需要高达 30 秒。

© www.soinside.com 2019 - 2024. All rights reserved.