pandas.DataFrame, Seriesの要素の値を置換するreplace
pandas.DataFrame
, pandas.Series
の要素の値を置換するには、replace()
メソッドを使う。
複数の異なる要素を一括で置き換えたり正規表現を使ったりすることもできる。
- pandas.DataFrame.replace — pandas 1.1.2 documentation
- pandas.Series.replace — pandas 1.1.2 documentation
ここでは以下の内容について説明する。
- 要素を置換
- 複数の異なる要素を一括で置換
- 辞書で指定
- リストで指定
- 注意点
- 対象列を指定して置換
- 正規表現で置換
- 欠損値NaNの置換
- 元のオブジェクトを変更
例として以下のデータを使用する。説明のため一部要素の値を変更している。
import pandas as pd
print(pd.__version__)
# 1.0.5
df = pd.read_csv('data/src/sample_pandas_normal.csv')
df.iloc[1, 3] = 24
print(df)
# name age state point
# 0 Alice 24 NY 64
# 1 Bob 42 CA 24
# 2 Charlie 18 CA 70
# 3 Dave 68 TX 70
# 4 Ellen 24 CA 88
# 5 Frank 30 NY 57
サンプルのcsvファイルはコチラ。
例はpandas.DataFrame
だが、pandas.Series
でも同様。
なお、pandas.Series
に対してはmap()
メソッドで置換することも可能。正規表現は使えないが、すべての要素を別の値に置換するのであればreplace()
よりmap()
のほうが高速になる場合が多い。
また、値を指定して置換するのではなく、条件に応じて値を変更する方法は以下の記事を参照。
要素を置換
第一引数に元の要素の値、第二引数に置換後の値を指定する。
print(df.replace('CA', 'California'))
# name age state point
# 0 Alice 24 NY 64
# 1 Bob 42 California 24
# 2 Charlie 18 California 70
# 3 Dave 68 TX 70
# 4 Ellen 24 California 88
# 5 Frank 30 NY 57
すべての列の要素が対象となる。特定の列の値のみ置換したい場合については後述。
print(df.replace(24, 100))
# name age state point
# 0 Alice 100 NY 64
# 1 Bob 42 CA 100
# 2 Charlie 18 CA 70
# 3 Dave 68 TX 70
# 4 Ellen 100 CA 88
# 5 Frank 30 NY 57
デフォルトでは要素を置換した新たなDataFrame
が返されるが、引数inplace=True
とすると元のDataFrame
が変更される。最後に例を紹介する。
複数の異なる要素を一括で置換
複数の異なる要素を一括で置き換えたい場合は、辞書を使う方法とリストを使う方法がある。
辞書で指定
第一引数に{元の値: 置換後の値}
の辞書を指定する。
print(df.replace({'CA': 'California', 24: 100}))
# name age state point
# 0 Alice 100 NY 64
# 1 Bob 42 California 100
# 2 Charlie 18 California 70
# 3 Dave 68 TX 70
# 4 Ellen 100 California 88
# 5 Frank 30 NY 57
リストで指定
第一引数に元の値のリスト、第二引数に置換後の値のリストを指定する。リストのサイズ(要素数)が一致していないとエラー。
print(df.replace(['CA', 24], ['California', 100]))
# name age state point
# 0 Alice 100 NY 64
# 1 Bob 42 California 100
# 2 Charlie 18 California 70
# 3 Dave 68 TX 70
# 4 Ellen 100 California 88
# 5 Frank 30 NY 57
# print(df.replace(['CA', 24, 'NY'], ['California', 100]))
# ValueError: Replacement lists must match in length. Expecting 3 got 2
第二引数にスカラー値を指定するとすべての要素がその値に置換される。
print(df.replace(['CA', 24], 'XXX'))
# name age state point
# 0 Alice XXX NY 64
# 1 Bob 42 XXX XXX
# 2 Charlie 18 XXX 70
# 3 Dave 68 TX 70
# 4 Ellen XXX XXX 88
# 5 Frank 30 NY 57
注意点
複数の置換ペアのあいだで元の値と置換後の値が一致している場合は注意。
Python3.7.4, pandas0.22.0では、順番によっては置換された値がさらに置換される場合があった。以下のコードのみ古い環境での結果なので注意。
print(df.replace({'CA': 'NY', 'NY': 'XXX'}))
# name age state point
# 0 Alice 24 XXX 64
# 1 Bob 42 XXX 24
# 2 Charlie 18 XXX 70
# 3 Dave 68 TX 70
# 4 Ellen 24 XXX 88
# 5 Frank 30 XXX 57
print(df.replace({'NY': 'XXX', 'CA': 'NY'}))
# name age state point
# 0 Alice 24 XXX 64
# 1 Bob 42 NY 24
# 2 Charlie 18 NY 70
# 3 Dave 68 TX 70
# 4 Ellen 24 NY 88
# 5 Frank 30 XXX 57
print(df.replace(['CA', 'NY'], ['NY', 'XXX']))
# name age state point
# 0 Alice 24 XXX 64
# 1 Bob 42 XXX 24
# 2 Charlie 18 XXX 70
# 3 Dave 68 TX 70
# 4 Ellen 24 XXX 88
# 5 Frank 30 XXX 57
print(df.replace(['NY', 'CA'], ['XXX', 'NY']))
# name age state point
# 0 Alice 24 XXX 64
# 1 Bob 42 NY 24
# 2 Charlie 18 NY 70
# 3 Dave 68 TX 70
# 4 Ellen 24 NY 88
# 5 Frank 30 XXX 57
Python3.8.5, pandas1.0.5では、辞書でもリストでも、どのような順番で指定しても置換された値がさらに置換されることはない。
print(df.replace({'CA': 'NY', 'NY': 'XXX'}))
# name age state point
# 0 Alice 24 XXX 64
# 1 Bob 42 NY 24
# 2 Charlie 18 NY 70
# 3 Dave 68 TX 70
# 4 Ellen 24 NY 88
# 5 Frank 30 XXX 57
print(df.replace({'NY': 'XXX', 'CA': 'NY'}))
# name age state point
# 0 Alice 24 XXX 64
# 1 Bob 42 NY 24
# 2 Charlie 18 NY 70
# 3 Dave 68 TX 70
# 4 Ellen 24 NY 88
# 5 Frank 30 XXX 57
print(df.replace(['CA', 'NY'], ['NY', 'XXX']))
# name age state point
# 0 Alice 24 XXX 64
# 1 Bob 42 NY 24
# 2 Charlie 18 NY 70
# 3 Dave 68 TX 70
# 4 Ellen 24 NY 88
# 5 Frank 30 XXX 57
print(df.replace(['NY', 'CA'], ['XXX', 'NY']))
# name age state point
# 0 Alice 24 XXX 64
# 1 Bob 42 NY 24
# 2 Charlie 18 NY 70
# 3 Dave 68 TX 70
# 4 Ellen 24 NY 88
# 5 Frank 30 XXX 57
どのバージョンから挙動が変わったかは未確認だが要注意。明確に順序を指定したい場合はreplace()
を繰り返し呼び出せばよい。
print(df.replace('CA', 'NY').replace('NY', 'XXX'))
# name age state point
# 0 Alice 24 XXX 64
# 1 Bob 42 XXX 24
# 2 Charlie 18 XXX 70
# 3 Dave 68 TX 70
# 4 Ellen 24 XXX 88
# 5 Frank 30 XXX 57
print(df.replace('NY', 'XXX').replace('CA', 'NY'))
# name age state point
# 0 Alice 24 XXX 64
# 1 Bob 42 NY 24
# 2 Charlie 18 NY 70
# 3 Dave 68 TX 70
# 4 Ellen 24 NY 88
# 5 Frank 30 XXX 57
対象列を指定して置換
{列名: {元の値: 置換後の値}}
という辞書を第一引数に指定することで対象列の要素のみを置換できる。辞書の要素を増やせば複数列、複数値を一括で置換可能。
print(df.replace({'age': {24: 100}}))
# name age state point
# 0 Alice 100 NY 64
# 1 Bob 42 CA 24
# 2 Charlie 18 CA 70
# 3 Dave 68 TX 70
# 4 Ellen 100 CA 88
# 5 Frank 30 NY 57
print(df.replace({'age': {24: 100, 18: 0}, 'point': {24: 50}}))
# name age state point
# 0 Alice 100 NY 64
# 1 Bob 42 CA 50
# 2 Charlie 0 CA 70
# 3 Dave 68 TX 70
# 4 Ellen 100 CA 88
# 5 Frank 30 NY 57
元の値と置換後の値をリストで指定することはできない。
# print(df.replace({'age': [[24, 18], [100, 0]], 'point': {24: 50}}))
# TypeError: If a nested mapping is passed, all values of the top level mapping must be mappings
すべて同じ値に置換したい場合は、第一引数に{列名: 元の値}
の辞書、第二引数に置換後の値をスカラー値で指定する。第一引数の元の値はリストで指定可能。
print(df.replace({'age': 24, 'point': 70}, 100))
# name age state point
# 0 Alice 100 NY 64
# 1 Bob 42 CA 24
# 2 Charlie 18 CA 100
# 3 Dave 68 TX 100
# 4 Ellen 100 CA 88
# 5 Frank 30 NY 57
print(df.replace({'age': [24, 18], 'point': 70}, 100))
# name age state point
# 0 Alice 100 NY 64
# 1 Bob 42 CA 24
# 2 Charlie 100 CA 100
# 3 Dave 68 TX 100
# 4 Ellen 100 CA 88
# 5 Frank 30 NY 57
正規表現で置換
引数regex=True
とすると、正規表現を使うことができる。
例えば、デフォルトでは要素の値が完全に一致した場合のみ置換されるので、一部だけ一致していても置換されない。
print(df.replace('li', 'LI'))
# name age state point
# 0 Alice 24 NY 64
# 1 Bob 42 CA 24
# 2 Charlie 18 CA 70
# 3 Dave 68 TX 70
# 4 Ellen 24 CA 88
# 5 Frank 30 NY 57
例えば要素の文字列の一部を置換したい場合、引数regex=True
として、正規表現で設定する。
()
で囲んだ部分をグループとして、置換後の値の中で\1
, \2
のように順番に使用可能。
print(df.replace('(.*)li(.*)', r'\1LI\2', regex=True))
# name age state point
# 0 ALIce 24 NY 64
# 1 Bob 42 CA 24
# 2 CharLIe 18 CA 70
# 3 Dave 68 TX 70
# 4 Ellen 24 CA 88
# 5 Frank 30 NY 57
regex=True
とした場合は、第一引数に正規表現パターン、第二引数に置換後の文字列を指定する。使い方は正規表現モジュールreのre.sub()
と同様。より詳しい例は以下の記事を参照。
特定の列の要素の文字列の一部を置換したい場合は文字列メソッドstr.replace()
を使う方法もある。
df['name'] = df['name'].str.replace('li', 'LI')
print(df)
# name age state point
# 0 ALIce 24 NY 64
# 1 Bob 42 CA 24
# 2 CharLIe 18 CA 70
# 3 Dave 68 TX 70
# 4 Ellen 24 CA 88
# 5 Frank 30 NY 57
詳細は以下の記事参照。
欠損値NaNの置換
欠損値NaN
の置換には、fillna()
というメソッドが用意されている。
replace()
を使っても可能だが、fillna()
だと行や列によって異なる値に置き換えたりできる。
詳細は以下の記事参照。
元のオブジェクトを変更
デフォルトでは要素を置換した新たなDataFrame
が返されるが、引数inplace=True
とすると元のDataFrame
が変更される。
df = pd.read_csv('data/src/sample_pandas_normal.csv')
print(df)
# name age state point
# 0 Alice 24 NY 64
# 1 Bob 42 CA 92
# 2 Charlie 18 CA 70
# 3 Dave 68 TX 70
# 4 Ellen 24 CA 88
# 5 Frank 30 NY 57
df.replace('CA', 'California', inplace=True)
print(df)
# name age state point
# 0 Alice 24 NY 64
# 1 Bob 42 California 92
# 2 Charlie 18 California 70
# 3 Dave 68 TX 70
# 4 Ellen 24 California 88
# 5 Frank 30 NY 57