【问题标题】:speed up pandas series.rolling.appy()加快熊猫 series.rolling.apply()
【发布时间】:2020-02-22 15:15:20
【问题描述】:

我需要计算 pandas 系列滚动窗口内所有值的乘积,忽略 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 或者是否有滚动窗口的内置产品功能(如果可能,忽略 nan)?在文档中找不到它

【问题讨论】:

  • 为了降低开销,请尝试将您的 Series 转换为 numpy 数组,然后对其进行操作。
  • 你为什么要把np.nanprod.mean()比较?
  • @jorijnsmit %timeit -n100 a.rolling(5).apply(np.mean,raw=False) 11.3 ms ± 59.6 µs per loop (mean ± std. dev. of 7 runs, 100 loops each),这是应用程序放慢速度时发生的事情,而不是意味着。我将np.nanprodmean 进行比较,因为没有内置产品功能,否则我的整个问题将不存在。
  • @J_H 会尝试,虽然 numpy 中的滚动功能不像 pandas 中那么直观

标签: python-3.x pandas rolling-computation


【解决方案1】:

解决问题的方法是 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 值,但速度应该明显更好。

【讨论】:

  • 这个答案解决了我的问题,缺失值很容易添加并设置为原始 pd.Series
【解决方案2】:

实际上有一个.prod() 函数默认忽略NA/null 值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-30
    • 2021-10-17
    • 2019-12-15
    • 1970-01-01
    • 1970-01-01
    • 2018-11-17
    • 2021-09-17
    • 2018-04-28
    相关资源
    最近更新 更多