pandas 中的动态滚动功能

Posted

技术标签:

【中文标题】pandas 中的动态滚动功能【英文标题】:Dynamic rolling function in pandas 【发布时间】:2021-11-16 05:01:50 【问题描述】:

我正在尝试在 Pandas 中实现动态移动平均线和其他动态移动函数,例如 stdmax。 “正常”和动态移动平均线之间的区别在于边缘的行为。这主要改进了两件事:

返回的数据没有像“正常”移动平均线那样移动 返回的数据覆盖了输入数据的整个范围。使用“正常”移动平均线,根据移动平均线的窗口大小裁剪返回的数据范围。

所以要获得动态移动平均线,有多种方法,如 反射、重复第一个/最后一个值,...对我来说,反射方法就足够了。此行为和其他行为在来自scripy.ndimage.filters 的过滤器中实现,例如uniform_filter1d。我已经查看了 Pandas 文档,但在 rolling 上我找不到任何改变边缘行为的参数...... 自己添加这个似乎是可行的,但我问这个问题,看看我是否已经错过了 Pandas 中的实现。

所以我的问题可以简化为:有没有办法像我描述的那样动态使用 Pandas rolling

“正常”移动平均线

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy.ndimage import filters


def moving_avg(series: pd.Series, window: int) -> pd.Series:
    return series.rolling(window=window).mean()


t = np.linspace(0, 100, 1000)
y = np.sin(2 * np.pi * 0.03 * t)

filtered_y = filters.uniform_filter1d(y, 200)

pd_y = pd.Series(y, name="Pandas Moving Average")
pd_y = moving_avg(pd_y, 200) # Using a large window on purpose to show the shift!

plt.plot(y, label="Raw Data")
plt.plot(filtered_y, label="uniform_filter1d")
pd_y.plot()
plt.legend()
plt.show()

结果

那么有什么办法可以解决这个问题吗?

【问题讨论】:

为什么不能使用scipy 过滤器? 我将使用不同的 Pandas rolling 方法,例如 stdmax,但我只发现 uniform_filter1d 与我期望的 mean 的结果相似。 @Drachen 首先可以使用rolling 方法中的参数center=True 解决“移位”问题 是的,我阅读了有关此参数的信息,但这不会改变边缘行为。有没有办法动态实现rolling函数? @Drachen 您只是在寻找一种简单的方法来实现熊猫滚动中uniform_filter1d 的模式反射? 【参考方案1】:

我不认为你想要实现什么。一种简单的方法是使用concat 添加边缘值以创建反射效果。在函数中,它可能类似于

def rolling_reflect_center(s, window):
    nb_ref = window // 2
    rolling_ = pd.concat(
        [pd.Series(s.iloc[:nb_ref].values)[::-1],#reflect on the left
         s, 
         pd.Series(s.iloc[-nb_ref+1:].values[::-1]) #reflect on the right
        ]).rolling(window ,center=True)
    return rolling_

那你就做

filtered_y = filters.uniform_filter1d(y, 200)

pd_y = pd.Series(y, name="Pandas Moving Average")
pd_y = rolling_reflect_center( pd_y, window=200).mean()

print(np.allclose(pd_y.dropna().to_numpy(),filtered_y))
#True

情节也很好,因为它会自动删除nan

【讨论】:

感谢 Ben.T 的努力。我认为 Pandas 中没有实现相同的效果(边缘行为,'shift')并且您的解决方案工作正常,所以接受您的答案!:) @Drachen 感谢您的编辑

以上是关于pandas 中的动态滚动功能的主要内容,如果未能解决你的问题,请参考以下文章

在 pandas 扩展/滚动功能中,如何使用数据框或系列的索引?

加快pandas groupby中的滚动总和计算

从 Pandas 中的滚动窗口生成值组合

在内置“滚动”之外对 Pandas Dataframe 进行滚动窗口操作的最佳方法?

pandas 中的前瞻性滚动窗口 - 参差不齐的索引

从 Pandas DataFrame 中的滚动总和中获取原始值