【发布时间】:2019-10-06 09:45:09
【问题描述】:
TL;DR:我的问题是如何改进我的功能以超越 pandas 自身的最大移动功能?
背景信息:
所以我正在处理大量移动平均线、移动最大值和移动最小值等,到目前为止,我发现的唯一移动窗口之类的功能位于 pandas.rolling method。问题是:我拥有的数据是 numpy 数组,我想要的最终结果也必须在 numpy 数组中;尽管我想简单地将其转换为 pandas 系列并返回 numpy 数组来完成这样的工作:
result2_max = pd.Series(data_array).rolling(window).max().to_numpy()
,转换数据类型似乎没有必要,而且在 numpy 实现中可能有一些方法可以做完全相同的事情。
然而,尽管它看起来很不合 Python,但它比我想出的或在网上看到的任何方法都快。我将在下面给出小基准:
import numpy as np
import pandas as pd
def numpy_rolling_max(data, window):
data = data[::-1]
data_strides = data.strides[0]
movin_window = np.lib.stride_tricks.as_strided(data,
shape=(data.shape[0] - window +1, window),
strides = (data_strides ,data_strides)
)[::-1]
max_window =np.amax(movin_window, axis = 1)#this line seems to be the bottleneck
nan_array = np.full(window - 1, np.nan)
return np.hstack((nan_array, max_window))
def pandas_rolling_max(data, window):
return pd.Series(data).rolling(window).max().to_numpy()
length = 120000
window = 190
data = np.arange(length) + 0.5
result1_max = numpy_rolling_max(data, window)#21.9ms per loop
result2_max = pandas_rolling_max(data, window)#5.43ms per loop
result_comparision = np.allclose(result1_max, result2_max, equal_nan = True)
在 arraysize = 120k,window = 190 的情况下,pandas 滚动最大值比 numpy 版本快大约 3 倍。我不知道从哪里开始,因为我已经尽可能地矢量化了我自己的函数,但它仍然比 pandas 版本慢得多,我真的不知道为什么。
提前谢谢你
编辑:我找到了瓶颈,就是这一行:
max_window =np.amax(movin_window, axis = 1)
但是看到已经是向量化的函数调用,我还是不知道怎么继续。
【问题讨论】:
-
你在 numpy 中尝试过
convolve -
@WeNYoBen 我没有,也不知道 convolve 有什么帮助....你介意告诉我怎么做吗?
-
@WeNYoBen 检查了它,不幸的是,熊猫默认版本似乎优于该帖子下面的答案; np.convolve 也不会在以下解决方案的任何部分中发挥作用:/
-
你试用过 Scipy 版本吗(从 scipy.ndimage.filters 导入 maximum_filter1d 之一)-stackoverflow.com/a/43288787?
标签: python pandas performance numpy rolling-computation