note.nkmk.me

pandas.DataFrame, Seriesの要素の値を置換するreplace

Date: 2018-01-22 / Modified: 2019-08-21 / tags: Python, pandas

pandas.DataFrame, pandas.Seriesの要素の値を置換するには、replace()メソッドを使う。

複数の異なる要素を一括で置き換えたり正規表現を使ったりすることもできる。

ここでは以下の内容について説明する。

  • 要素を置換
  • 複数の異なる要素を一括で置換
    • 辞書で指定
    • リストで指定
    • 注意点
  • 対象列を指定して置換
  • 正規表現で置換
  • 欠損値NaNの置換
  • 元のオブジェクトを変更

例として以下のデータを使用する。説明のため一部要素の値を変更している。

import pandas as pd

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

注意点

複数の置換ペアのあいだで元の値と置換後の値が一致している場合は注意。順番に置換されていくので、置換された値が更に置換される。順番によって結果が異なる。

辞書の例。

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

Python3.7以降は辞書の順序が保持されているが、それより前のバージョンでは不定。上の結果のようになるとは限らない。明確に順序を指定したい場合はreplace()を繰り返し呼び出す。

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(['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

対象列を指定して置換

{列名: {元の値: 置換後の値}}という辞書を第一引数に指定することで対象列の要素のみを置換できる。辞書の要素を増やせば複数列、複数値を一括で置換可能。

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
スポンサーリンク
シェア
このエントリーをはてなブックマークに追加

関連カテゴリー

関連記事