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_replacevalue引数を指定します。


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関数も有効です。

参考