python - Dask:真正懒惰的排序
问题描述
如果我有一个未知分区的数据集,并且想根据列对其进行排序并输出到 Parquet,在我看来,Dask 至少做了两次工作:
import dask
import dask.dataframe as dd
def my_identity(x):
"""Does nothing, but shows up on the Dask dashboard"""
return x
df = dask.datasets.timeseries()
df = df.map_partitions(my_identity)
df = df.set_index(['name']) # <- `my_identity` is calculated here, as well as other tasks
df.to_parquet('temp.parq') # <- previous tasks seem to be recalculated here
如果my_identity
计算要求很高,那么重新计算将非常昂贵。
我对 Dask 在这里做了两次工作的理解是否正确?有什么办法可以防止这种情况发生吗?
解决方案
下面的解释可能不准确,但希望能有所帮助。
让我们试着在这方面进入 dask 的立场。我们要求 dask 基于某个变量创建索引...... Dask 仅适用于已排序的索引,因此 Dask 将想知道如何重新排列数据以使其排序,以及分区的适当划分是什么。您看到的第一个计算就是这样做的,dask 将仅存储划分/数据重组所需的计算部分。
然后,当我们要求 Dask 保存数据时,它会计算变量、打乱数据(与之前的计算一致)并将其存储在相应的分区中。
如何避免这种情况?可能的选项:
persist
在设置索引之前。一旦你坚持,dask 将计算变量并将其保留在工作人员上,因此设置索引将引用该计算的结果。仍将重新洗牌所需的数据)。请注意,文档建议在设置索引后保留,但这种情况假定该列存在(不需要单独计算)。在分区内排序,这可以懒惰地完成,但当然,如果您不需要全局排序,这只是一种选择。
使用 plain
pandas
,这可能需要对数据进行一些手动分块(我倾向于用于排序)。
推荐阅读
- c++ - 自动调整阴影贴图投影(通过将兴趣点投影到光源的近剪裁平面上)
- c# - 我想在 nlog mongo 配置中将集合名称作为变量
- mysql - SQL - 使用另一个表中的值和合法格式检查约束
- php - SQL查询转换为laravel
- google-cloud-platform - 如何增加 Google Analytics 中的“每用户帐户数限制”?
- c++ - 类模板名称中的隐藏朋友与内联命名空间中的另一个符号冲突
- python - 根据R中的特定列值提取行
- angular - 如何通过rxjs从对象数组中过滤出元素数组
- dictionary - 我可以使用 defer 删除地图的元素吗?
- javascript - Axios mock - 多个嵌套的 axios 请求 - 问题以及如何测试它?