【发布时间】:2022-01-18 22:26:28
【问题描述】:
我有兴趣在大型一维 numpy 数组上计算滚动窗口中的统计信息。对于小窗口大小,使用 numpy strides (a la numpy.lib.stride_tricks.sliding_window_view) 比 pandas 滚动窗口实现更快,但对于大窗口大小则相反。
考虑以下几点:
import numpy as np
from numpy.lib.stride_tricks import sliding_window_view
import pandas as pd
data = np.random.randn(10**6)
data_pandas = pd.Series(data)
window = 2
%timeit np.mean(sliding_window_view(data, window), axis=1)
# 19.3 ms ± 255 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit data_pandas.rolling(window).mean()
# 34.3 ms ± 688 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
window = 1000
%timeit np.mean(sliding_window_view(data, window), axis=1)
# 302 ms ± 8.01 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit data_pandas.rolling(window).mean()
# 31.7 ms ± 958 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
result_numpy = np.mean(sliding_window_view(data, window), axis=1)
result_pandas = data_pandas.rolling(window).mean()[window-1:]
np.allclose(result_numpy, result_pandas)
# True
对于较大的窗口大小,pandas 实现实际上更快,而 numpy 实现慢得多。
在 pandas 的底层发生了什么,我们如何使用 numpy 获得类似的性能?
与 pandas 相比,我如何在 numpy 的大窗口上获得类似的性能?
【问题讨论】:
-
这个问题是开放式的,不适用于已发布的答案。您可能会考虑将问题中的最后一条语句改写为“与 Pandas 相比,我如何在 NumPy 的大窗口上获得类似的性能?”,假设有答案。讨论内部实现细节通常超出了 Stackoverflow 问题的范围。
-
与
sliding_window的创建时间基本相同,但最大的时间差异在于取(999999, 2)与(999001, 1000)的平均值。这是合理的。查看pd.rolling(...).mean的文档,我看到一个engine参数,它可能是cython或numba。所以pandas正在做它自己专门的compiled.calculation。 -
已修复 @scootermefecit 感谢您的建议。
标签: python pandas numpy performance rolling-computation