Dask数据帧known_divisions和性能

时间:2017-08-07 21:35:58

标签: python dask

我有几个文件,其中有一个名为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 |

1 个答案:

答案 0 :(得分:1)

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

在第二个版本中,您断言所选列是索引,但是如果没有明确要求,dask不会对数据进行洗牌。如果它碰巧在镶木地板元数据中保存了统计数据,并且每个镶木地板块的最大/最小值是这样的,那么它们就会形成一个单调的系列(即,第二个块中的所有值' idx'如果大于第一个中的所有值,等等,那么对于涉及索引的某些操作,您将具有已知的除法和优化的性能。如果不满足这些条件,则设置索引列,但不知道除法 - 这对于计算长度也是完全正确的。