单个索引是否永远不能位于两个不同的分区中?
不,这当然是允许的。达斯克甚至打算让这种情况发生。然而,由于一个bug https://github.com/dask/dask/issues/8437 in set_index
,所有数据仍将位于一个分区中。
一个极端的例子(除了一个之外,每一行都是相同的值):
In [1]: import dask.dataframe as dd
In [2]: import pandas as pd
In [3]: df = pd.DataFrame({"A": [0] + [1] * 20})
In [4]: ddf = dd.from_pandas(df, npartitions=10)
In [5]: s = ddf.set_index("A")
In [6]: s.divisions
Out[6]: (0, 0, 0, 0, 0, 0, 0, 1)
如您所见,Dask 的目的是0
要在多个分区之间分割。然而,当洗牌真正发生时,所有的0
s 仍然最终位于一个分区中:
In [7]: import dask
In [8]: dask.compute(s.to_delayed()) # easy way to see the partitions separately
Out[8]:
([Empty DataFrame
Columns: []
Index: [],
Empty DataFrame
Columns: []
Index: [],
Empty DataFrame
Columns: []
Index: [],
Empty DataFrame
Columns: []
Index: [],
Empty DataFrame
Columns: []
Index: [],
Empty DataFrame
Columns: []
Index: [],
Empty DataFrame
Columns: []
Index: [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]],)
这是因为code https://github.com/dask/dask/blob/a5aecac8313fea30c5503f534c71f325b1775b9c/dask/dataframe/shuffle.py#L796决定一行属于哪个输出分区不考虑重复项divisions
。治疗divisions
作为一个系列,它使用searchsorted https://pandas.pydata.org/docs/reference/api/pandas.Series.searchsorted.html with side="right"
,这就是为什么所有数据总是在最后一个分区中结束的原因。
问题解决后我会更新这个答案。