我在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接受一个参数,而不是允许选择每边尺寸的参数,并且似乎存在数据不足的问题。
除了滚动以外,还有其他替代方法吗?还是我需要自己滚动?
答案 0 :(得分:1)
我不确定在没有进一步测试的情况下这是否可以在所有情况下使用。
让我们发挥创意。在“滚动窗口”中向后使用rolling
和shift
以获取适当的尾随行和前行数。要以滚动平均值的方式处理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