加速 pandas series.rolling.appy()
speed up pandas series.rolling.appy()
我需要为 pandas 系列计算滚动 windows 内所有值的乘积,忽略 nan。
我正在使用 pandas.Series.rolling.apply 作为当前方法,但与内置函数相比速度相当慢,我正在处理巨大的数据帧,因此速度是我关心的问题。
作为示范:
import pandas as pd
a = pd.Series(range(100))
%timeit -n100 a.rolling(5).apply(np.nanprod,raw=True)
5.58 ms ± 163 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit -n100 a.rolling(5).mean()
236 µs ± 19 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
所以 apply()
比内置 mean
函数慢很多
1 有没有办法加快申请过程
2 或者是否有用于滚动的内置乘积函数 window(如果可能,请忽略 nan)?无法在文档中找到它
实际上有一个 .prod()
函数默认忽略 NA/null 值。
解决您的问题的方法是 as_strided Numpy 函数。
要使用它,请定义以下函数:
def roll_win(a, win):
shape = a.shape[:-1] + (a.shape[-1] - win + 1, win)
strides = a.strides + (a.strides[-1],)
return np.lib.stride_tricks.as_strided(a, shape=shape, strides=strides)
然后根据这个函数的结果调用np.nanprod:
np.nanprod(roll_win(a.values, 5), axis=1)
区别在于结果是一个Numpy一维数组,没有4个初始的NaN
值,但速度应该明显更好。
我需要为 pandas 系列计算滚动 windows 内所有值的乘积,忽略 nan。
我正在使用 pandas.Series.rolling.apply 作为当前方法,但与内置函数相比速度相当慢,我正在处理巨大的数据帧,因此速度是我关心的问题。
作为示范:
import pandas as pd
a = pd.Series(range(100))
%timeit -n100 a.rolling(5).apply(np.nanprod,raw=True)
5.58 ms ± 163 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit -n100 a.rolling(5).mean()
236 µs ± 19 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
所以 apply()
比内置 mean
函数慢很多
1 有没有办法加快申请过程
2 或者是否有用于滚动的内置乘积函数 window(如果可能,请忽略 nan)?无法在文档中找到它
实际上有一个 .prod()
函数默认忽略 NA/null 值。
解决您的问题的方法是 as_strided Numpy 函数。
要使用它,请定义以下函数:
def roll_win(a, win):
shape = a.shape[:-1] + (a.shape[-1] - win + 1, win)
strides = a.strides + (a.strides[-1],)
return np.lib.stride_tricks.as_strided(a, shape=shape, strides=strides)
然后根据这个函数的结果调用np.nanprod:
np.nanprod(roll_win(a.values, 5), axis=1)
区别在于结果是一个Numpy一维数组,没有4个初始的NaN 值,但速度应该明显更好。