【问题标题】:Pandas - moving average with different time windowsPandas - 不同时间窗口的移动平均线
【发布时间】:2019-01-01 11:38:28
【问题描述】:

我在 Pandas 数据框中有一些数据。我想根据该数据计算移动平均值,包括最多 N 个尾随行和 Q 个前导行:

import pandas

my_data = pandas.DataFrame({
    'values': [5.0, 4.0, 3.0, 5.0, 5.0, 6.0, 4.0, 6.0, 7.0, 4.0, 5.0, 5.0]
})

my_data
    values
0      5.0
1      4.0
2      3.0
3      5.0
4      5.0
5      6.0
6      4.0
7      6.0
8      7.0
9      4.0
10     5.0
11     5.0

N=2
Q=3

get_moving_average(my_data, lagging=N, leading=Q)
    values      mavg
0        5  4.250000
1        4  4.400000
2        3  4.666667
3        5  4.500000
4        5  4.833333
5        6  5.500000
6        4  5.333333
7        6  5.333333
8        7  5.166667
9        4  5.400000
10       5  5.250000
11       5  4.666667

在这里,第 0 行的移动平均值为 4.25 - 单元格 0 的值加上 0 个粗体滞后行(因为没有)和 3 个斜体前导行(单元格的值 1:3 - 所以(5.0 + 4.0 + 3.0 + 5.0) / 4.0 = 17.0 / 4.0 = 4.25

第 1 行的移动平均线包括上述所有内容,还包括粗体的尾随行 0(因为我们接受 2 个滞后行,但只有一个存在),产生 (5.0 + 4.0 + 3.0 + 5.0 + 5.0) / 5.0 = 22.0 / 5.0 = 4.4。

等等。但是,pandas 的 rolling 方法只接受一个窗口参数,而不是允许选择每一边的大小,并且似乎存在数据不足的问题。

是否有替代滚动的替代方法,或者我需要自己滚动?

【问题讨论】:

  • 还没有测试过,但有没有可能my_data.expanding(4, center=False).mean()
  • 不,因为那只是一面。我需要双方控制

标签: python pandas


【解决方案1】:

如果没有进一步测试,我不确定这是否适用于所有情况。

让我们发挥创意。在“滚动窗口”中向后使用rollingshift 以获得适当的尾随和前导行数。为了处理滚动平均值的 NaN,让我们向后滚动 fillna

N=2
Q=3
T = N+Q+1
my_data.rolling(T, min_periods=1).mean().shift(-Q)\
       .fillna(my_data[::-1].rolling(T, min_periods=Q).mean().shift(-N)[::-1])

输出:

      values
0   4.250000
1   4.400000
2   4.666667
3   4.500000
4   4.833333
5   5.500000
6   5.333333
7   5.333333
8   5.166667
9   5.400000
10  5.250000
11  4.666667

步骤:

在整个间隔内进行滚动计算,在您的情况下,将是 N(滞后)+ Q(领先)和总和为总和 (T) 的电流。

my_data.rolling(T, min_periods=1).mean()

现在,让我们将使用 shift 的计算向后移动,以使窗口符合预期,N 滞后,Q 超前,所以 shift -Q。

my_data.rolling(T, min_periods=1).mean().shift(-Q)

输出:

      values
0   4.250000
1   4.400000
2   4.666667
3   4.500000
4   4.833333
5   5.500000
6   5.333333
7   5.333333
8   5.166667
9        NaN
10       NaN
11       NaN

现在为了处理数据帧末尾的那些 NaN 值,我们反向进行滚动计算并使用 fillna 填充原始值。 [::-1] 是一个反转元素,从末尾开始滚动到开头,然后使用 [::-1] 再次翻转以与原始结果对齐。

my_data[::-1].rolling(T, min_periods=Q).mean().shift(-N)[::-1]

输出:

      values
0        NaN
1        NaN
2   4.666667
3   4.500000
4   4.833333
5   5.500000
6   5.333333
7   5.333333
8   5.166667
9   5.400000
10  5.250000
11  4.666667

在第一个系列和第二个系列上使用 fillna 来获得:

N=2
Q=3
T = N+Q+1
my_data.rolling(T, min_periods=1).mean().shift(-Q)\
       .fillna(my_data[::-1].rolling(T, min_periods=Q).mean().shift(-N)[::-1])

输出:

      values
0   4.250000
1   4.400000
2   4.666667
3   4.500000
4   4.833333
5   5.500000
6   5.333333
7   5.333333
8   5.166667
9   5.400000
10  5.250000
11  4.666667

【讨论】:

  • 好的,这很好。在第一次通过时,这绝对有效——你能把它分解一下吗?您在那里有大约 7 个不同的调用链接在一起,我不确定我是否会一步一步地跟踪正在发生的事情。
  • @J.Doe 更新了更多细节。
猜你喜欢
  • 2020-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-26
  • 1970-01-01
  • 2010-11-04
  • 2023-03-23
  • 1970-01-01
相关资源
最近更新 更多