我有一个带有每月数据的pandas数据框,我想计算12个月的移动平均值。然而,每年1月份的数据都缺失(NaN),因此我正在使用
pd.rolling_mean(data["variable"]), 12, center=True)
但是它只给了我所有的NaN值。
有没有简单的方法可以忽略NaN值?我知道实际上这将变成一个11个月的移动平均。
数据框中有其他具有1月数据的变量,因此我不想仅丢弃1月列并进行11个月的移动平均。
我有一个带有每月数据的pandas数据框,我想计算12个月的移动平均值。然而,每年1月份的数据都缺失(NaN),因此我正在使用
pd.rolling_mean(data["variable"]), 12, center=True)
但是它只给了我所有的NaN值。
有没有简单的方法可以忽略NaN值?我知道实际上这将变成一个11个月的移动平均。
数据框中有其他具有1月数据的变量,因此我不想仅丢弃1月列并进行11个月的移动平均。
有几种方法可以处理这个问题,最好的方法取决于1月份的数据是否与其他月份有系统性的不同。大多数真实世界中的数据很可能具有某种季节性,因此让我们以北半球一个随机城市的平均高温(华氏度)为例。
有几种方法可以处理这个问题,最好的方法取决于1月份的数据是否与其他月份有系统性的不同。大多数真实世界中的数据很可能具有某种季节性,因此让我们以北半球一个随机城市的平均高温(华氏度)为例。df=pd.DataFrame({ 'month' : [10,11,12,1,2,3],
'temp' : [65,50,45,np.nan,40,43] }).set_index('month')
你可以像你所建议的那样使用滚动平均值,但问题在于你会得到整个年度的平均温度,这忽略了一月份是最冷的事实。为了纠正这个问题,你可以将窗口减小到3,这将导致一月份的温度是十二月和二月温度的平均值。(我还使用了min_periods=1
,就像@user394430的回答中建议的一样。)df['rollmean12'] = df['temp'].rolling(12,center=True,min_periods=1).mean()
df['rollmean3'] = df['temp'].rolling( 3,center=True,min_periods=1).mean()
这些是改进,但仍存在通过滚动平均覆盖现有值的问题。为了避免这种情况,您可以与update()
方法结合使用(请参见此处的文档)。
df['update'] = df['rollmean3']
df['update'].update( df['temp'] ) # note: this is an inplace operation
甚至还有更简单的方法,它可以保留现有值,同时将缺失的一月温度填充为上个月、下个月或前后两个月平均值。
df['ffill'] = df['temp'].ffill() # previous month
df['bfill'] = df['temp'].bfill() # next month
df['interp'] = df['temp'].interpolate() # mean of prev/next
在这种情况下,interpolate()
默认使用简单线性插值,但你还可以选择多种其他的插值选项。请参阅 pandas interpolate 文档 获取更多信息。或者查看这个 stack overflow 问题:在 pandas 中对 DataFrame 进行插值
以下是带有所有结果的示例数据: temp rollmean12 rollmean3 update ffill bfill interp
month
10 65.0 48.6 57.500000 65.0 65.0 65.0 65.0
11 50.0 48.6 53.333333 50.0 50.0 50.0 50.0
12 45.0 48.6 47.500000 45.0 45.0 45.0 45.0
1 NaN 48.6 42.500000 42.5 45.0 40.0 42.5
2 40.0 48.6 41.500000 40.0 40.0 40.0 40.0
3 43.0 48.6 41.500000 43.0 43.0 43.0 43.0
特别注意,"update"和"interp"在所有月份中都会产生相同的结果。虽然在这里使用哪一个都无所谓,但在其他情况下,一种方法可能比另一种更好。
关键在于设置 min_periods=1
。从18版本开始,正确的调用方法是使用Rolling对象。 因此,您的代码应该是
data["variable"].rolling(min_periods=1, center=True, window=12).mean()
。
min_periods=1
是解决问题的关键。感谢你提供了滚动对象的建议。 - MyCarta