Dask DataFrame设索引后head()返回空表,tail()正常且重置索引无效的问题
解决Dask DataFrame设置索引后head()返回空的问题
我之前也碰到过一模一样的问题,其实根源在于Dask设置非数值索引后的分区逻辑,咱们一步步拆解:
为什么会出现这个问题?
当你用set_index('bhello')把字符串列设为索引时,Dask会对数据进行洗牌分区(基于索引的哈希值分配到不同分区)。这就导致原来Pandas DataFrame里的前几条数据,被分散到了后面的分区中——而df.head()默认只会检查第一个分区的前n条数据,自然就返回空DataFrame了。
至于reset_index()没用,是因为它只是把索引变回普通列,但洗牌后的分区结构并没有改变,第一个分区还是没有数据,所以head()依然拿不到内容。而df.tail()是读取最后一个分区的后n条,刚好那个分区有数据,所以能正常返回。
解决方案
这里有两个实用的解决办法,根据你的数据规模选择:
方法1:让head()检查所有分区(推荐)
修改head()的npartitions参数为-1,这样Dask会遍历所有分区来收集前n条数据,而不是只局限于第一个分区:
import dask.dataframe as dd import pandas as pd import numpy as np data = pd.DataFrame({ 'i64': np.arange(1000, dtype=np.int64), 'Ii32': np.arange(1000, dtype=np.int32), 'bhello': np.random.choice(['hello', 'Yo', 'people'], size=1000).astype("O") }) daskDf = dd.from_pandas(data, chunksize=3) daskDf = daskDf.set_index('bhello') # 修改head的npartitions参数 print(daskDf.head(n=5, npartitions=-1))
这个方法不需要加载全量数据,性能上比直接compute更友好,适合大数据场景。
方法2:先compute成Pandas DataFrame(小数据场景)
如果你的数据量不大,能完全加载到内存,可以先把Dask DataFrame转换成Pandas DataFrame再取head:
print(daskDf.compute().head())
但注意:如果数据规模很大,这个方法会占用大量内存,不推荐使用。
内容的提问来源于stack exchange,提问作者pranav kohli
相关产品推荐
相关产品推荐

