pandas.DataFrame, Seriesの要素の値を置換するreplace
pandasでDataFrame
, Series
の要素の値を置換するにはreplace()
メソッドを使う。複数の異なる要素を一括で置換したり、正規表現で文字列の一部分のみを置換したりすることもできる。
- pandas.DataFrame.replace — pandas 2.1.3 documentation
- pandas.Series.replace — pandas 2.1.3 documentation
Series
に対してはmap()
メソッドで置換することも可能。正規表現は使えないが、条件によってはreplace()
よりmap()
のほうが高速になる場合もある。
値を指定して置換するのではなく、条件に応じて値を置換する方法は以下の記事を参照。
本記事のサンプルコードのpandasのバージョンは以下の通り。バージョンによって仕様が異なる可能性があるので注意。例として以下のデータを使用する。説明のため一部要素の値を変更している。
import pandas as pd
print(pd.__version__)
# 2.1.2
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
例はDataFrame
だがSeries
でも使い方は同じ。
要素を置換
第一引数に元の値、第二引数に置換後の値を指定する。
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
対象列を指定して置換
第一引数に{列名: {元の値: 置換後の値}}
の辞書を指定すると、対象列の要素のみを置換できる。辞書の要素を増やせば複数列・複数値を一括で置換可能。
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', 'XX'))
# 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()
を使って置換される。
第一引数に正規表現パターン、第二引数に置換後の文字列を指定する。例えばe
で終わる文字列を置換する例は以下の通り。.
が任意の文字、*
が0回以上の繰り返し、$
が文字列の末尾を表す。
print(df.replace('.*e$', 'NEW_NAME', regex=True))
# name age state point
# 0 NEW_NAME 24 NY 64
# 1 Bob 42 CA 24
# 2 NEW_NAME 18 CA 70
# 3 NEW_NAME 68 TX 70
# 4 Ellen 24 CA 88
# 5 Frank 30 NY 57
正規表現の特殊文字を使わない場合、単純に指定した部分文字列が置換される。
print(df.replace('li', 'XX', regex=True))
# name age state point
# 0 AXXce 24 NY 64
# 1 Bob 42 CA 24
# 2 CharXXe 18 CA 70
# 3 Dave 68 TX 70
# 4 Ellen 24 CA 88
# 5 Frank 30 NY 57
()
で囲んだ部分をグループとして、置換後の値の中で\1
, \2
のように使うこともできる。
print(df.replace('(.*)li(.*)', r'\2-\1', regex=True))
# name age state point
# 0 ce-A 24 NY 64
# 1 Bob 42 CA 24
# 2 e-Char 18 CA 70
# 3 Dave 68 TX 70
# 4 Ellen 24 CA 88
# 5 Frank 30 NY 57
re.sub()
についての詳細は以下の記事を参照。
特定の列の要素の文字列の一部を置換したい場合は文字列メソッドstr.replace()
を使う方法もある。
df['name'] = df['name'].str.replace('li', 'XX')
print(df)
# name age state point
# 0 AXXce 24 NY 64
# 1 Bob 42 CA 24
# 2 CharXXe 18 CA 70
# 3 Dave 68 TX 70
# 4 Ellen 24 CA 88
# 5 Frank 30 NY 57
詳細は以下の記事参照。
欠損値NaNの置換
欠損値NaN
の置換には、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