Pandasでデータの値を置換したい時はreplace
関数がよく使われます。
本記事ではreplace
関数の使い方について解説します。
replace関数
APIドキュメント
replace
関数のAPIドキュメントは以下の通りです。
DataFrameだけでなくSeriesにも適用できます。
pandas.DataFrame.replace(to_replace=None,value=None,inplace=False,limit=None,regex=False,method=’pad’)
params:
パラメータ名 | 型 | 概要 |
---|---|---|
to_replace | str,正規表現 リスト,辞書,Series int,float もしくはNone |
(省略可能)初期値None 置換したい値を指定します。指定の仕方によっては置換した後の値も指定します。 |
value | スカラー,辞書,リスト str,正規表現,None |
(省略可能)初期値None to_replaceで指定された値を置換する値をここで指定します。辞書形式だと列ごとに置換したい値を指定できます。 |
inplace | bool値 | (省略可能)初期値False Trueの時、変更を元のデータに反映させます。 |
limit | int | (省略可能)初期値None 値を補完する時の最大繰り返し回数を指定します。 |
regex | boolまたは 正規表現 |
(省略可能)初期値False to_replaceやvalueで指定された値を正規表現として処理するかどうかを指定します。またはここに直接正規表現を指定します。 |
method | ‘pad’,’ffill’, ‘bfill’,None |
(省略可能)初期値None to_replaceで指定された値がスカラーやリスト、タプルで、valueがNoneの時、どのような方法で補完をするかを指定します。 |
returns:
値が置換されたDataFrameが返されます。
to_replaceやvalueで様々な置換の指定をできるので1つ1つみていきましょう。
1つの値に対して1つの置換をする
1つの値に対して1つの置換をする時はスカラー値でto_replace
とvalue
引数を指定します。
In [1]: import pandas as pd
In [2]: sr = pd.Series(range(7))
In [3]: sr
Out[3]:
0 0
1 1
2 2
3 3
4 4
5 5
6 6
dtype: int64
In [4]: sr.replace(3,10) # 3を10に変更する
Out[4]:
0 0
1 1
2 2
3 10
4 4
5 5
6 6
dtype: int64
DataFrameに対しても同様です。
In [1]: import pandas as pd
In [2]: sr = pd.Series(range(7))
In [3]: sr
Out[3]:
0 0
1 1
2 2
3 3
4 4
5 5
6 6
dtype: int64
In [4]: sr.replace(3,10) # 3を10に変更する
Out[4]:
0 0
1 1
2 2
3 10
4 4
5 5
6 6
dtype: int64
複数の値に対して1つの値を置換する
複数の置換する対象がある場合はリスト、タプルで指定します。
In [8]: sr
Out[8]:
0 0
1 1
2 2
3 3
4 4
5 5
6 6
dtype: int64
In [9]: sr.replace([0,1,2,3],-99) # 0,1,2,3を-99に置換する
Out[9]:
0 -99
1 -99
2 -99
3 -99
4 4
5 5
6 6
dtype: int64
In [10]: df
Out[10]:
A B C
0 0 4 a
1 1 5 b
2 2 6 c
3 3 7 d
In [11]: df.replace([0,1,'a'],-99) # 文字列も指定可能
Out[11]:
A B C
0 -99 4 -99
1 -99 5 b
2 2 6 c
3 3 7 d
In [12]: df.replace((0,1,'a'),-99) # タプルでも指定できる
Out[12]:
A B C
0 -99 4 -99
1 -99 5 b
2 2 6 c
3 3 7 d
複数の値に対してそれぞれ置換する値を指定する
複数の値に対してそれぞれ1つずつ置換する値を決めたい時は辞書が使えます。
In [13]: sr
Out[13]:
0 0
1 1
2 2
3 3
4 4
5 5
6 6
dtype: int64
In [14]: sr.replace({0:-1,1:-2,2:-3}) # 1つずつ個別に指定
Out[14]:
0 -1
1 -2
2 -3
3 3
4 4
5 5
6 6
dtype: int64
In [15]: df
Out[15]:
A B C
0 0 4 a
1 1 5 b
2 2 6 c
3 3 7 d
In [16]: df.replace({0:'b','a':-20})
Out[16]:
A B C
0 b 4 -20
1 1 5 b
2 2 6 c
3 3 7 d
リストとリストの組み合わせやタプルとタプルでも同様の指定が可能です。
In [17]: sr.replace([0,1,2],[-1,-2,-3])
Out[17]:
0 -1
1 -2
2 -3
3 3
4 4
5 5
6 6
dtype: int64
In [18]: df.replace([0,'a'],['b',-20])
Out[18]:
A B C
0 b 4 -20
1 1 5 b
2 2 6 c
3 3 7 d
列ごとに置換する値を変える
第2引数であるvalue
引数を辞書形式で指定するとキーを列名にして列ごとに置換する値を決めることができます。
DataFrameに対してのみ有効です。
In [20]: df_2 = pd.DataFrame({'A':[0,1,2],
...: 'B':[0,1,2],
...: 'C':[0,1,2]})
...:
In [21]: df_2
Out[21]:
A B C
0 0 0 0
1 1 1 1
2 2 2 2
In [22]: df_2.replace(0,{'A':'a','B':'b','C':'c'})
Out[22]:
A B C
0 a b c
1 1 1 1
2 2 2 2
正規表現を使って置換する
正規表現を使って値を指定することが可能となります。
regex=True
にすると指定した値を正規表現として処理してくれます。
stack overflowの質問にあった例で考えていきます。
In [30]: df_3 = pd.DataFrame({'A':['Syslog','Syslog','Syslog','Syslog'],
...: 'B':['PD380_003 %LINK-3-UPDOWN','NM380_005 %BGP-5-NBR_RESET','NM380_005 %BGP-5-NBR_RESET','DO NOT TICKET LO380_004 %SYS-5-CONFIG_I Config']})
...:
In [31]: df_3
Out[31]:
A B
0 Syslog PD380_003 %LINK-3-UPDOWN
1 Syslog NM380_005 %BGP-5-NBR_RESET
2 Syslog NM380_005 %BGP-5-NBR_RESET
3 Syslog DO NOT TICKET LO380_004 %SYS-5-CONFIG_I Config
In [32]: df_3.replace('^.*([A-Z]{2}[0-9]{3}_[0-9]{3}).*$', {'B':r'\1'},regex=True)
Out[32]:
A B
0 Syslog PD380_003
1 Syslog NM380_005
2 Syslog NM380_005
3 Syslog LO380_004
このように正規表現を使って値を指定し、置換することが可能です。
無効な値を前後の値で埋めあわせる
例えば、以下のようなデータがあったとします。
In [33]: data = pd.Series([0, 1, 3, -999, -999, -999, 5, 2, -999, -999, 1])
In [34]: data
Out[34]:
0 0
1 1
2 3
3 -999
4 -999
5 -999
6 5
7 2
8 -999
9 -999
10 1
dtype: int64
この時、-999という値が無効な値として考えられるので前後の値で埋め合わせをしてみます。
fillna
をより一般化した形で使っているイメージです。fillna
関数の使い方は以下の記事で詳しく解説しています。
Pandasでnan値を削除穴埋めするfillnaとdropnaの使い方 /features/pandas-manipulate-na.html#欠損値を穴埋めする方法
In [35]: data.replace(-999) # 第一引数だけ指定すれば埋め合わせをしてくれる
Out[35]:
0 0
1 1
2 3
3 3
4 3
5 3
6 5
7 2
8 2
9 2
10 1
dtype: int64
デフォルトではmethod='pad'
となっているので、直前の値をそのまま使用する形で埋め合わせをしています。
逆に直後の値を使用したい時はmethod='bfill'
を指定します。
In [36]: data.replace(-999,method='bfill')
Out[36]:
0 0
1 1
2 3
3 5
4 5
5 5
6 5
7 2
8 1
9 1
10 1
dtype: int64
今度は繰り返し回数を制限します。limit
引数に値を指定すればできます。
今回は最大2回までにしてみましょう。
In [37]: data.replace(-999,limit=2)
Out[37]:
0 0
1 1
2 3
3 3
4 3
5 -999
6 5
7 2
8 2
9 2
10 1
dtype: int64
まとめ
今回はreplace
関数の使い方について解説しました。
値の置換をするのが基本的な役目ですが、fillna
関数の拡張版として使うことも可能なのでうまく使えると非常に便利になると思います。
また、正規表現が使えるので文字列に対して複雑な文字の置換も指定することも可能です。文字列の置換についてはstr.replace
関数も有効です。
参考
- pandas.DataFrame.drop - pandas 0.23.4 documentation
- Python for Data Analysis 2nd edition –Wes McKinney(書籍)