我有几个文件,其中有一个名为idx
的列,我想将它用作索引。获得的数据帧大约有13M行。我知道我可以用这种方式读取和分配索引(这很慢〜40秒)
df = dd.read_parquet("file-*.parq")
df = df.set_index("idx")
或以其他方式(快速~40毫秒)
df = dd.read_parquet("file-*.parq", index = "idx")
使用第二种方法计算长度的简单操作快约4倍。我不明白的是
df.known_divisions
上返回True
,而在第二个案例False
上。我期待相反的行为。然后我在df
之上做了几次操作,没有一个已知的分区,我总能获得更好的性能。我正在摸不着头脑,弄清楚这是否是故意发生的。 更新
这不仅仅是计算更快的len
。在我的计算中,我使用groupby创建了4个新的数据帧,多次应用和连接,这些是时间
| |Load and reindex (s)|Load with index (s)|
|:-----------------|-------------------:|------------------:|
| load | 12.5000 | 0.0124 |
| grp, apply, join | 11.4000 | 6.2700 |
| compute() | 146.0000 | 125.0000 |
| TOTAL | 169.9000 | 131.2820 |
答案 0 :(得分:1)
当您使用第一种方法时,dask正在加载数据,并在执行您要求的任何计算之前,按所选列的值对其进行分区(这涉及对所有光盘上的块进行混洗)。在计算长度的情况下,这是所有浪费的时间,因为对索引划分的了解对此没有任何帮助,但涉及该索引的进一步计算(例如,连接操作)会快得多。 / p>
在第二个版本中,您断言所选列是索引,但是如果没有明确要求,dask不会对数据进行洗牌。如果它碰巧在镶木地板元数据中保存了统计数据,并且每个镶木地板块的最大/最小值是这样的,那么它们就会形成一个单调的系列(即,第二个块中的所有值' idx'如果大于第一个中的所有值,等等,那么对于涉及索引的某些操作,您将具有已知的除法和优化的性能。如果不满足这些条件,则设置索引列,但不知道除法 - 这对于计算长度也是完全正确的。