正如文档所述,当调用reset_index
时,Dask会在每个分区的基础上创建一个严格增加的索引,从而导致整个集合上出现重复索引。在整个集合中,在Dask中创建严格增加的索引(不必连续)的最佳方法(例如计算最快)是什么?我希望map_partitions
会传递分区号,但我认为不会。感谢。
修改
感谢@MRocklin,我已经做到了这一点,但我需要一些帮助来解决如何将我的系列与原始数据帧重新组合。
def create_increasing_index(ddf:dd.DataFrame):
mps = int(len(ddf) / ddf.npartitions + 1000)
values = ddf.index.values
def do(x, max_partition_size, block_id=None):
length = len(x)
if length == 0:
raise ValueError("Does not work with empty partitions. Consider using dask.repartition.")
start = block_id[0] * max_partition_size
return da.arange(start, start+length, chunks=1)
series = values.map_blocks(do, max_partition_size=mps, dtype=np.int64)
ddf2 = dd.concat([ddf, dd.from_array(series)], axis=1)
return ddf2
我收到错误“ValueError:无法将DataFrame与指定axis = 1的未知分区连接”。有没有比使用dd.concat更好的方法?感谢。
再次编辑
实际上,出于我的目的(以及我正在测试的数据量 - 只有几gb),cumsum足够快。当这变得太慢时,我会重温一下!
答案 0 :(得分:1)
实现这一目标的一种相当缓慢的方法是创建一个新列,然后使用cumsum
ddf['x'] = 1
ddf['x'] = ddf.x.cumsum()
ddf = ddf.set_index('x', sorted=True)
这既不是很慢也不是免费的。
考虑到你的问题是如何表达的,我怀疑你只是想为每个分区创建一个范围,该范围由一个非常大的值分隔,你知道这个值大于最大行数。你是对的map_partitions
没有提供分区号。您可以改为执行以下两种解决方案之一。
.values
),使用map_blocks
方法,该方法提供块索引,然后转换回dd.from_array
的系列。dd.from_delayed
转换回dask系列