我有一个包含 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分钟左右。
我一定是在这里做错了什么。
与 pandas 类似,
dask_df[1]
实际上会引用一列,而不是一行。因此,如果您有一个名为 1
的列,那么您只是从整个框架中加载一个列。您不能按位置访问行 - df.iloc
仅支持沿第二(列)轴的索引。如果您的索引中有值1
,您可以使用df.loc
选择它,例如:
df.loc[1].compute()
有关索引的dask.dataframe 文档有关更多信息和示例。
在未索引的数据帧上执行
.loc
时,Dask 将需要解压缩整个文件。由于每个分区都有自己的索引,.loc[N]
将检查每个分区的N
,请参阅this answer。
解决这个问题的一种方法是支付一次生成唯一索引并保存索引的 parquet 文件的成本。这样
.loc[N]
只会从包含行N
.的特定分区(或行组)加载信息
使用示例方法。
您没有掌握 dask 和 pandas 之间的必要区别之一……分布式索引。这意味着必须使用 loc 至少检查所有文件上的元数据,并且您还可能遇到出现在多个(可能是索引未排序的)分区中的索引。
如果您需要随机数据,请使用示例。 Loc 用于其他用途,与 pandas 的 loc 不同。