熊猫-不同时间窗的移动平均线

时间:2018-07-24 18:42:36

标签: python pandas

我在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 < em> + 3.0 + 5.0 + 5.0 )/ 5.0 = 22.0 / 5.0 = 4.4。

以此类推。但是,pandas的rolling方法仅对window接受一个参数,而不是允许选择每边尺寸的参数,并且似乎存在数据不足的问题。

除了滚动以外,还有其他替代方法吗?还是我需要自己滚动?

1 个答案:

答案 0 :(得分: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领先,所以将-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