Ale*_*ont 11 python moving-average missing-data pandas
我有一个带有月度数据的熊猫数据框,我想计算12个月的移动平均值.但是,(NaN)缺少1月份每个月的数据,所以我正在使用
pd.rolling_mean(data["variable"]), 12, center=True)
Run Code Online (Sandbox Code Playgroud)
但它只是给了我所有的NaN值.
有一种简单的方法可以忽略NaN值吗?据我所知,在实践中,这将成为11个月的移动平均线.
数据框还有其他具有1月数据的变量,所以我不想抛弃1月份的列并做11个月的移动平均线.
Joh*_*hnE 15
有几种方法可以解决这个问题,最好的方法取决于1月数据是否与其他月份系统地不同.大多数现实世界的数据可能都是季节性的,所以让我们以北半球随机城市的平均高温(华氏温度)为例.
df=pd.DataFrame({ 'month' : [10,11,12,1,2,3],
'temp' : [65,50,45,np.nan,40,43] }).set_index('month')
Run Code Online (Sandbox Code Playgroud)
您可以按照建议使用滚动平均值,但问题是您将获得全年的平均温度,这忽略了1月是最冷月的事实.要纠正此问题,您可以将窗口缩小为3,这会导致1月临时值是12月和2月临时值的平均值.(我也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()
Run Code Online (Sandbox Code Playgroud)
这些都是改进,但仍然存在用滚动方式覆盖现有值的问题.为避免这种情况,您可以结合使用该update()方法(请参阅此处的文档).
df['update'] = df['rollmean3']
df['update'].update( df['temp'] ) # note: this is an inplace operation
Run Code Online (Sandbox Code Playgroud)
甚至有更简单的方法可以单独保留现有值,同时用上个月,下个月或上个月和下个月的平均值填充缺失的1月临时值.
df['ffill'] = df['temp'].ffill() # previous month
df['bfill'] = df['temp'].bfill() # next month
df['interp'] = df['temp'].interpolate() # mean of prev/next
Run Code Online (Sandbox Code Playgroud)
在这种情况下,interpolate()默认为简单的线性解释,但您也有其他几个插值选项.有关详细信息,请参阅有关pandas interpolate的文档.或者这个statck溢出问题:
在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
Run Code Online (Sandbox Code Playgroud)
特别要注意,"更新"和"interp"在所有月份都会给出相同的结果.虽然你在这里使用哪一个并不重要,但在其他情况下,这种或那种方式可能会更好.