Dask 数据帧 known_divisions 和性能

Dask dataframes known_divisions and performance

我有几个文件,其中有一个名为 idx 的列,我想将其用作索引。获得的数据框有大约 13M 行。我知道我可以用这种方式读取和分配索引(这很慢 ~40 秒)

df = dd.read_parquet("file-*.parq")
df = df.set_index("idx")

或以这种其他方式(快约 40 毫秒)

df = dd.read_parquet("file-*.parq", index = "idx")

计算长度的简单操作使用第二种方法快约 4 倍。我不明白的是

更新 这不仅仅是计算 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 |

当您使用第一种方法时,dask 正在加载数据,并在执行您要求的任何计算之前根据您选择的列的值对行进行分区(这涉及打乱所有磁盘上的块)为了。在计算长度的情况下,这都是浪费时间,因为了解索引划分对此毫无帮助,但涉及该索引的进一步计算(例如,连接操作)会快得多。

在第二个版本中,您断言您选择的列是索引,但 dask 不会在您没有明确要求的情况下打乱数据。如果它碰巧在 parquet 元数据中保存了统计信息,并且每个 parquet 块的 max/min 是这样的,那么它们形成一个单调序列(即,第二个块中 'idx' 的所有值都是大于第一个中的所有值,等等),那么您将像以前一样知道涉及索引的某些操作的除法和优化性能。如果不满足这些条件,则设置了索引列,但分区未知 - 同样,这对于计算长度完全没问题。