我有一个具有以下格式的数据框:
日期时间 | 价值 | 马 |
---|---|---|
1 月 1 日 | 1 | 无 |
1 月 2 日 | 2 | 无 |
1 月 3 日 | 1 | 无 |
1 月 4 日 | 不适用 | 无 |
1 月 5 日 | 2 | 无 |
1 月 6 日 | 不适用 | 无 |
1 月 7 日 | 不适用 | 无 |
1 月 8 日 | 3 | 无 |
我希望以最后 3 个非空值为条件计算“Value”列的移动平均值。
所需输出:
日期时间 | 价值 | 马 |
---|---|---|
1 月 1 日 | 1 | 1 |
1 月 2 日 | 2 | 1.5 |
1 月 3 日 | 1 | 1.33 |
1 月 4 日 | 无 | 1.33 |
1 月 5 日 | 2 | 1.67 |
1 月 6 日 | 无 | 1.67 |
1 月 7 日 | 无 | 1.67 |
1 月 8 日 | 3 | 2 |
例如,在 1 月 8 日的行中,移动平均值取最后 3 个非空值 (3,2,1) 来给出值 2,而 1 月 3 日的行仅取 (1,2,1) 来计算移动平均线。因此,由于这种情况,我无法使用 moving.mean() 方法。我还尝试尽可能避免使用循环,因为数据帧很大。解决这个问题的最佳方法是什么?
dropna
删除 NaN,然后使用 rolling.mean
计算
reindex
和
method=ffill
来填充缺失值:
df['MA'] = (df.dropna(subset=['Value'])['Value']
.rolling(3, min_periods=1).mean()
.reindex(df.index, method='ffill')
)
输出:
Datetime Value MA
0 1 Jan 1.0 1.000000
1 2 Jan 2.0 1.500000
2 3 Jan 1.0 1.333333
3 4 Jan NaN 1.333333
4 5 Jan 2.0 1.666667
5 6 Jan NaN 1.666667
6 7 Jan NaN 1.666667
7 8 Jan 3.0 2.000000
Series.dropna
去除缺失值,计算滚动平均值,然后前向缺失值:
df['MA'] = df['Value'].dropna().rolling(3, min_periods=1).mean()
df['MA'] = df['MA'].ffill()
或者用方法Series.reindex
添加
ffill
:
df['MA'] = (df['Value'].dropna().rolling(3, min_periods=1).mean()
.reindex(df.index, method='ffill'))
print (df)
Datetime Value MA
0 1 Jan 1.0 1.000000
1 2 Jan 2.0 1.500000
2 3 Jan 1.0 1.333333
3 4 Jan NaN 1.333333
4 5 Jan 2.0 1.666667
5 6 Jan NaN 1.666667
6 7 Jan NaN 1.666667
7 8 Jan 3.0 2.000000