web-dev-qa-db-ja.com

NaNまたは欠落値を移動平均または他の補間に置き換えます

pandas 12か月の移動平均を計算したい月次データを含むデータフレームがあります。1月の各月のデータが欠落していますが(NaN)、使用しています

pd.rolling_mean(data["variable"]), 12, center=True)

しかし、それは私にすべてのNaN値を与えるだけです。

NaN値を無視できる簡単な方法はありますか?実際には、これは11か月の移動平均になることを理解しています。

データフレームには1月のデータを持つ他の変数があるため、1月の列を破棄して、11か月の移動平均を実行したくありません。

11

これにアプローチする方法はいくつかありますが、最善の方法は、1月のデータが他の月と体系的に異なるかどうかによって異なります。ほとんどの実際のデータは季節的なものである可能性が高いため、例として北半球のランダムな都市の平均最高気温(華氏)を使用してみましょう。

_df=pd.DataFrame({ 'month' : [10,11,12,1,2,3],
                  'temp'  : [65,50,45,np.nan,40,43] }).set_index('month')
_

あなたが提案するように移動平均を使用することもできますが、問題は、1月が最も寒い月であるという事実を無視して、年間の平均気温が得られることです。これを修正するには、ウィンドウを3に減らすことができます。これにより、1月の気温は12月と2月の気温の平均になります。 (@ user394430の回答で提案されているように、私も_min_periods=1_を使用しています。)

_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
_

欠落している1月の臨時雇用者を前月、翌月、または前月と翌月の平均で埋めながら、既存の値をそのままにするさらに簡単なアプローチがあります。

_df['ffill']   = df['temp'].ffill()         # previous month 
df['bfill']   = df['temp'].bfill()         # next month
df['interp']  = df['temp'].interpolate()   # mean of prev/next
_

この場合、interpolate()はデフォルトで単純な線形解釈になりますが、他にもいくつかの補間オプションがあります。詳細については、 documentation on pandas interpolate を参照してください。またはこのstatckオーバーフローの質問: パンダの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」はすべての月で同じ結果をもたらすことに注意してください。ここでどちらを使用するかは問題ではありませんが、他の場合はどちらかが良い場合があります。

16
JohnE

本当の鍵は_min_periods=1_を持つことです。また、バージョン18以降、適切な呼び出しは Rolling object を使用します。したがって、コードは次のようになります。

data["variable"].rolling(min_periods=1, center=True, window=12).mean()

12
user394430