(財)気象業務支援センター「気象データベース」をPythonのpandasでハンドリングしたときのtipsです.この気象データの紹介がこちらにありますが,項目毎に値とリマークの時系列が連続したカラムとして収録されています.例として,一部を抜粋し,pandasのDataFrameとして示します.ただし,ダミーの値を入れています.avrLhpaは日平均現地気圧,avrShpaは日平均海面気圧,avrKionは日平均気温です.これらにRMKが付いたものがリマークで,8が正常,1が欠測を意味するとします.欠損の場合は空白になっていて,pandasで自動的にNaNにすることもできますが,一般には値0が入っているけれども欠損値にしたいといった場合もあります.このようにRMKの値に応じてその変数の値をNaN等に書き換える方法を考えます.方針は,対象となるRMKのカラム番号を抽出し,その一つ前の番号のカラムの値を指定した値で置換する,です.

>>> df

            avrLhpa avrLhpaRMK  avrShpa avrShpaRMK  avrKion avrKionRMK
YYYY_MM_DD                     
1961-12-01  1015.8  8   1016.5  8   10.3    8
1961-12-02  1014.2  8        0  3   11.8    8
1961-12-03  1020.0  8   1020.7  8   11.7    8
1961-12-04  1018.0  8   1018.7  8   7.4 8
1961-12-05  1021.1  8   1021.8  8   6.3 8

文字列RMKを含むカラム名をリストとして抽出します.

>>> RMK_cols = [col for col in df.columns if 'RMK' in col]
>>> RMK_cols

['avrLhpaRMK', 'avrShpaRMK', 'avrKionRMK']

カラム名からカラム番号を求める

カラム’arvShpaRMK’のカラム番号を抽出するには次のようにします.

>>> df.columns.get_loc('avrShpaRMK')

3

よって,idx=3-1=2が該当カラムの番号になります.

RMKの値が対象値のとき,その変数の値を置換する

avrShpaRMK=3のときのavrShpaの値をNaNに置換するには以下のようにします.ただし,avrShpaRMKのカラム番号idxは上で求めた通り,idx=2です.

df.iloc[:, idx].mask(df['avrShpaRMK'] == 3, np.nan, inplace=True)

df.iloc[:, idx]で当該カラムを抽出し,.mask()の第1引数に条件を与え,第2引数に置換する値を与えます.第3引数のinplace=Truedf自体を更新することを意味します.

RMK全カラムを対象に指定したRMK値のリストを渡し一度に置換する

以上の方法をRMKカラムのリストRMK_colsのすべてに拡張し,RMK値がrmk_nans=[1, 3, 4, 5]のときの項目値をすべてNaNにするには,以下のようにforループで回します.

for rmk_col in RMK_cols:
    for rmk_nan in rmk_nans:
        idx = df.columns.get_loc(rmk_col) - 1  ### RMKに対応する値のカラムインデックス
        df.iloc[:, idx].mask(df[rmk_col] == rmk_nan, np.nan, inplace=True)