加速 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 值,但速度应该明显更好。