gpt4 book ai didi

python - 在大型数据集上使用 pandas 滚动 max 非常慢

转载 作者:行者123 更新时间:2023-12-02 11:36:39 24 4
gpt4 key购买 nike

我有一个 pandas 数据框 df它有一个跨越大约 2 年、2 列和超过 3000 万行的 float64 数据的 DatatimeIndex。我很快注意到 df.rolling('1d').mean() 之间的性能存在明显差异。和df.rolling('1d').max()

>>> n=100000; import timeit; r=df[:n].rolling('1d'); timeit.timeit(lambda: r.max(), number=1)
2.5886592870228924
>>> n=100000; import timeit; r=df[:n].rolling('1d'); timeit.timeit(lambda: r.mean(), number=1)
0.011829487979412079
>>> n=1000000; import timeit; r=df[:n].rolling('1d'); timeit.timeit(lambda: r.max(), number=1)
53.8340517100296
>>> n=1000000; import timeit; r=df[:n].rolling('1d'); timeit.timeit(lambda: r.mean(), number=1)
0.06093513499945402

如您所见,df.rolling('1d').mean()df.rolling('1d').max()快几百倍。我希望它会更快一些,因为计算最大 pandas 可能必须在每个步骤中跟踪滚动窗口中所有值的顺序。然而,很容易看出如何通过最多添加一个对数因子来实现这一点,因此我预计差异会更小。如果这是最好的办法,请使用 df.rolling('1d').max对于完整的数据集来说这将是一个痛苦,因为看起来每次都需要几个小时。

之前遇到过 pandas 的效率问题(Series.iloc 索引),我很好奇这是否是 pandas 问题,或者是否有更快的方法来解决此问题。

 

编辑

这个问题最近在 pandas 的 master 分支中得到了修复。即使在完整数据集上,现在也可以在 2.35 秒内计算出滚动最大值,而之前可能需要几个小时。感谢 hexgnu 的修复。

>>> runtime(lambda: df.rolling('1d').max())
2.3093386580003425
>>> n=100000; import timeit; r=df[:n].rolling('1d'); timeit.timeit(lambda: r.max(), number=1)
0.015023122999991756
>>> n=1000000; import timeit; r=df[:n].rolling('1d'); timeit.timeit(lambda: r.max(), number=1)
0.08013121400290402
>>> n=10000000; import timeit; r=df[:n].rolling('1d'); timeit.timeit(lambda: r.max(), number=1)
0.6795377829985227
>>> import timeit; r=df.rolling('1d'); timeit.timeit(lambda: r.max(), number=1)
2.3540661859951797
>>> len(df)
32819278

最佳答案

Pandas 正在使用运行 max 的简单实现, linear scan over the window for every sample 。因此,它是线性复杂度乘以窗口大小,即每天有数百个以上的样本,它将比平均值慢数百倍。

可能的解决方法:以分钟为单位,然后以小时为单位超过此最大值,然后以天为单位 - 它应该会导致一种对数效应,但常数可能会耗尽所有渐近优势。

更好的解决方案:为 pandas 贡献 heap min_max 实现

关于python - 在大型数据集上使用 pandas 滚动 max 非常慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48593118/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com