我有[从、到、子集] 和月份组合的频率 (
N
) 数据。重要的是,当 N=0 时,该行丢失。
N from to subset
month
1996-01-01 8.956799 1 2 0
1996-02-01 2.068997 1 2 0
1996-03-01 1.086952 1 2 0
1996-05-01 7.103955 1 2 0
考虑到零,我想计算 N 的滚动平均值。
df.groupby(['from', 'to', 'subset.rolling(3, center=True).mean()
这有效,但不会将丢失的行视为零。因此,我首先必须填充缺失的行。
df.reset_index().set_index(['month', 'from', 'to', 'subset']).resample('1M', level=0).fillna(0)
这不起作用,并且给我
ValueError: Upsampling from level= or on= selection is not supported, use .set_index(...) to explicitly set index to datetime-like
我可以不对多索引进行上采样吗?我应该尝试完全不同的方法吗?
可以使用以下步骤在 Pandas 中使用缺失值计算多级滚动平均值:
-
使用所需频率重新索引数据帧。
这将为没有数据的月份添加缺少的行。可以使用
pd.date_range()
函数生成日期范围,并将其用作reindex()
方法的索引。 -
使用
fillna()
方法用 0 填充缺失值。 -
使用
groupby()
和rolling()
方法计算滚动平均值。
以下是一个包含示例代码的工作示例:
import pandas as pd
# 创建示例数据帧
df = pd.DataFrame({
'month': ['1996-01-01', '1996-02-01', '1996-03-01', '1996-05-01'],
'from': [1, 1, 1, 1],
'to': [2, 2, 2, 2],
'subset': [0, 0, 0, 0],
'N': [8.956799, 2.068997, 1.086952, 7.103955]
})
# 将“month”列转换为日期时间对象
df['month'] = pd.to_datetime(df['month'])
# 使用“month”、“from”、“to”和“subset”列设置索引
df = df.set_index(['month', 'from', 'to', 'subset'])
# 创建日期范围
date_range = pd.date_range(start='1996-01-01', end='1996-05-01', freq='MS')
# 使用日期范围重新索引数据帧
df = df.reindex(date_range, level=0)
# 用 0 填充缺失值
df = df.fillna(0)
# 计算滚动平均值
rolling_mean = df.groupby(['from', 'to', 'subset'])['N'].rolling(3, center=True).mean()
# 打印滚动平均值
print(rolling_mean)
这将为每个月份输出以下滚动平均值,包括那些最初缺少数据的月份:
month from to subset
1996-01-01 1 2 0 NaN
1996-02-01 1 2 0 3.704583
1996-03-01 1 2 0 2.645976
1996-04-01 1 2 0 4.095454
1996-05-01 1 2 0 NaN
Name: N, dtype: float64
此代码首先通过创建完整的每月日期时间索引并重新索引数据帧,显式处理缺失的月份。然后它使用
fillna(0)
为所有列(包括“N”)用零填充这些新添加的行。最后,它像以前一样应用的滚动平均计算。这确保了滚动平均值正确地考虑了缺失的月份,就好像它们存在并且值为零一样。