pandasのreplace()は、DataFrameやSeriesの中にある値そのものを別の値に置き換えるためのメソッドです。
CSVを読み込んだあと、次のような値が混ざっていると、集計結果が分かれやすくなります。
- 「男性」「男」「M」のように、同じ意味なのに書き方が違う
- 「不明」「-」「なし」のように、本当は欠損値として扱いたい文字列が残っている
- 「カード」「クレカ」のように、集計前に表記をそろえたい値がある
この状態のままvalue_counts()やgroupby()を使うと、本当は同じ意味のデータが別々に数えられてしまいます。
この記事では、replace()の基本形、表記ゆれの修正、欠損値への変換、fillna()・rename()・map()・str.replace()との違いを、初心者向けに順番に整理します。
- まず結論:replace()は「列の中の値」をそろえるときに使う
- この記事でわかること
- Pandas前処理シリーズの中での位置づけ
- replace()とは?値そのものを置き換えるメソッド
- replace()の基本形を早見表で確認する
- replace()・fillna()・rename()・map()などの違い
- サンプルDataFrameを用意する
- pandas replace()の基本的な使い方|1つの値を置換する
- 複数の値をまとめて置換する
- 辞書を使って表記ゆれを統一する
- 特定の列だけを置換する
- 「不明」「-」「なし」を欠損値に変換する
- 置換前後を確認する
- replace()とmap()の違い
- pandas replace()が反映されない原因|代入していないのがよくある理由
- replace()とstr.replace()の違い|値全体か、文字列の一部か
- loc・where()・regex=Trueは補足として理解する
- 前処理の流れの中でreplace()を使うタイミング
- まとめ:replace()は値を整えて次の分析に進むための前処理
- 次に読みたい関連記事
- カテゴリから探す
- pandas replace()は何をするメソッドですか?
- 複数の値をまとめて置換できますか?
- 特定の列だけreplace()できますか?
- 「不明」や「-」を欠損値に変えるにはどうすればよいですか?
- replace()とfillna()はどう使い分けますか?
- replace()とrename()は何が違いますか?
- replace()とmap()は何が違いますか?
- replace()とstr.replace()は何が違いますか?
- regex=Trueは最初から覚える必要がありますか?
- inplace=Trueは使わないほうがよいですか?
- replace()を使ったのに元のDataFrameが変わらないのはなぜですか?
まず結論:replace()は「列の中の値」をそろえるときに使う
replace()は、列名ではなく、列の中に入っている値を置き換えるときに使います。
たとえば、次のような整理に向いています。
| やりたいこと | replace()でできる? | 主に使う方法 |
|---|---|---|
| 「男」を「男性」にする | できる | replace() |
| 「男」「M」をまとめて「男性」にする | できる | replace(["男", "M"], "男性") |
「不明」「-」「なし」をNaNにする |
できる | replace(["不明", "-", "なし"], np.nan) |
すでにあるNaNを「不明」で埋める |
別の関数が向く | fillna() |
| 列名を変える | できない | rename() |
| 文字列の一部だけを置換する | 別の関数が向く | str.replace() |
| 条件に合う行だけ変更する | 別の書き方が向く | loc |
迷ったときは、次のように考えると整理しやすいです。
値そのものをまとめて置き換えるなら
replace()、欠損値を埋めるならfillna()、列名を変えるならrename()、文字列の一部を直すならstr.replace()です。
まずは「どの値を、どの値に置き換えるのか」を決めてから、replace()を書いていきましょう。
この記事でわかること
replace()で値を置き換える基本形- 1つの値・複数の値・辞書を使った置換方法
- 特定の列だけを安全に置換する方法
- 「男性」「男」「M」のような表記ゆれを修正する流れ
- 「不明」「-」「なし」を
NaNに変換する方法 replace()とfillna()、rename()、map()、str.replace()の違い- 置換前後を
value_counts()やisnull()で確認する方法 replace()が反映されないときの原因と、inplace=Trueを基本的に使わない考え方
Pandas前処理シリーズの中での位置づけ
このページは、Pandasでデータ分析を進めるときの前処理に関する記事です。
学習の流れとしては、次のように考えると理解しやすくなります。
read_csv()でデータを読み込むhead()やinfo()で全体を確認するvalue_counts()で値のばらつきを見るrename()で列名を整えるreplace()で値の表記ゆれを直すisnull()やfillna()で欠損値を扱うastype()やto_datetime()で型を整えるgroupby()などで集計する
つまり、replace()は「集計や可視化の前に、値の表記をそろえる」ための処理です。
列名を整えるrename()と、欠損値を扱うfillna()のあいだに置くと、前処理の流れがつかみやすくなります。
replace()とは?値そのものを置き換えるメソッド
replace()は、DataFrameやSeriesの中にある値そのものを別の値に置き換えるためのメソッドです。
大事なのは、replace()が扱うのは列名ではなく、列の中の値だという点です。
| 変更したいもの | 使う方法 |
|---|---|
| 列の中の値を変えたい | replace() |
| 列名を変えたい | rename() |
| すでにある欠損値を埋めたい | fillna() |
| 文字列の一部だけを変えたい | str.replace() |
たとえば、「男」「M」を「男性」にそろえるような表記ゆれ修正はreplace()が向いています。
一方で、genderという列名を性別に変える場合はrename()を使います。ここを混同しないことが、最初のポイントです。
replace()の基本形を早見表で確認する
replace()にはいくつかの書き方がありますが、初心者のうちは次の4つを押さえるだけでも十分です。
| やりたいこと | 書き方の例 | 使う場面 |
|---|---|---|
| 1つの値を置換する | df["列名"].replace("置換前", "置換後") |
「男」を「男性」にする |
| 複数の値を同じ値に置換する | df["列名"].replace(["A", "B"], "C") |
「男」「M」をどちらも「男性」にする |
| 辞書で複数の置換ルールを書く | df["列名"].replace({"A": "X", "B": "Y"}) |
表記ゆれをまとめて直す |
| 欠損値に変換する | df["列名"].replace(["不明", "-"], np.nan) |
文字列の「不明」や「-」を欠損値として扱う |
基本形は次のとおりです。
df["列名"] = df["列名"].replace(置換前, 置換後)
左側のdf["列名"] =が重要です。
replace()は、置換した結果を返します。元のDataFrameに反映したい場合は、上のように置換結果を元の列に代入すると考えるとわかりやすいです。
replace()・fillna()・rename()・map()などの違い
replace()と似た場面で、fillna()、rename()、map()、str.replace()、loc、where()などが出てくることがあります。
最初に、使い分けを整理しておきます。
| やりたいこと | 主に使う方法 | 例 |
|---|---|---|
| 値そのものを置き換えたい | replace() |
「男」を「男性」にする |
欠損値NaNを埋めたい |
fillna() |
NaNを「不明」で埋める |
| 列名や行名を変えたい | rename() |
gender列を性別にする |
| 対応表に従って値を分類し直したい | map() |
A→1、B→2のように変換する |
| 文字列の一部だけ置き換えたい | str.replace() |
「1,200円」から「円」だけを削除する |
| 条件に合う行だけ変更したい | loc |
購入金額が0の行だけ修正する |
| 条件によって値を残す・置き換える | where() / mask() |
条件を満たさない値だけNaNにする |
迷ったときは、まず次の3つを確認します。
- 置き換えたいのは列名か、列の中の値か
- 値全体を置き換えたいのか、文字列の一部だけを直したいのか
- すべての同じ値を置き換えたいのか、条件に合う行だけ変更したいのか
この記事では、値そのものを置き換えるreplace()を中心に扱い、その他の方法は「どんなときに使い分けるか」がわかる範囲で説明します。
サンプルDataFrameを用意する
ここでは、顧客アンケートのような小さなデータを使います。
あえて、次のような「表記ゆれ」や「欠損扱いしたい値」を入れています。
| 列名 | 入っている値の例 | 直したいこと |
|---|---|---|
| 性別 | 「男性」「男」「M」「女性」「女」「F」 | 同じ意味の値をそろえる |
| 支払方法 | 「カード」「クレカ」 | 表記を統一する |
| 年代・来店日 | 「不明」「-」「なし」「未定」 | 欠損値として扱えるようにする |
実際のCSVでも、このような表記ゆれや欠損扱いしたい文字列が混ざっていることはよくあります。
import pandas as pd
import numpy as np
df = pd.DataFrame({
"顧客ID": [1, 2, 3, 4, 5, 6, 7, 8],
"性別": ["男性", "男", "M", "女性", "女", "F", "不明", "男性"],
"年代": ["20代", "30代", "不明", "40代", "30代", "-", "20代", "なし"],
"購入金額": [1200, 3000, 2500, 1800, 4200, 0, 1500, 2200],
"来店日": ["2025-04-01", "2025-04-02", "未定", "2025-04-05", "なし", "2025-04-07", "2025-04-08", "-"],
"支払方法": ["カード", "クレカ", "現金", "カード", "現金", "不明", "クレカ", "カード"]
})
df
| 顧客ID | 性別 | 年代 | 購入金額 | 来店日 | 支払方法 | |
|---|---|---|---|---|---|---|
| 0 | 1 | 男性 | 20代 | 1200 | 2025-04-01 | カード |
| 1 | 2 | 男 | 30代 | 3000 | 2025-04-02 | クレカ |
| 2 | 3 | M | 不明 | 2500 | 未定 | 現金 |
| 3 | 4 | 女性 | 40代 | 1800 | 2025-04-05 | カード |
| 4 | 5 | 女 | 30代 | 4200 | なし | 現金 |
| 5 | 6 | F | – | 0 | 2025-04-07 | 不明 |
| 6 | 7 | 不明 | 20代 | 1500 | 2025-04-08 | クレカ |
| 7 | 8 | 男性 | なし | 2200 | – | カード |
まずは、value_counts()で性別の値がどのように分かれているか確認します。
表記ゆれを直す前に、いきなり置換するのではなく、どの値がどれくらい入っているかを確認することが大切です。
df["性別"].value_counts(dropna=False)
| count | |
|---|---|
| 男性 | 2 |
| 男 | 1 |
| M | 1 |
| 女性 | 1 |
| 女 | 1 |
| F | 1 |
| 不明 | 1 |
このままだと、「男性」「男」「M」が別々の値として扱われます。
本当は同じ意味として集計したい場合は、replace()で表記をそろえる必要があります。まずは1つの値を置き換える基本形から見ていきます。
pandas replace()の基本的な使い方|1つの値を置換する
replace()の基本形は、次のように考えるとわかりやすいです。
Series.replace(置換前, 置換後)
たとえば、性別列の「男」を「男性」に置き換える場合は、次のように書きます。
ここでは元のdfを直接変えず、確認しやすいようにdf_basicというコピーを作って試します。
df_basic = df.copy()
df_basic["性別"] = df_basic["性別"].replace("男", "男性")
df_basic[["顧客ID", "性別"]]
| 顧客ID | 性別 | |
|---|---|---|
| 0 | 1 | 男性 |
| 1 | 2 | 男性 |
| 2 | 3 | M |
| 3 | 4 | 女性 |
| 4 | 5 | 女 |
| 5 | 6 | F |
| 6 | 7 | 不明 |
| 7 | 8 | 男性 |
「男」だけが「男性」に変わりました。
ただし、この段階では「M」はまだ残っています。
表記ゆれをきれいに直すには、1つずつ置換するより、複数の値をまとめて置換するほうがわかりやすいことが多いです。
複数の値をまとめて置換する
複数の値を同じ値に置き換えたい場合は、置換前の値をリストで指定できます。
たとえば、「男」と「M」をどちらも「男性」にしたい場合は、次のように書けます。
df_multi = df.copy()
df_multi["性別"] = df_multi["性別"].replace(["男", "M"], "男性")
df_multi["性別"].value_counts(dropna=False)
| count | |
|---|---|
| 男性 | 4 |
| 女性 | 1 |
| 女 | 1 |
| F | 1 |
| 不明 | 1 |
このように、複数の表記を1つの値にまとめられます。
ただし、性別列には「女」や「F」もあります。
男性と女性の両方をまとめて直す場合は、辞書を使って置換ルールをまとめると、コードの見通しがよくなります。
辞書を使って表記ゆれを統一する
複数の置換ルールをまとめたい場合は、辞書を使うと見通しがよくなります。
表記ゆれ修正では、次のように「置換前」と「置換後」の対応を決めてからコードにすると安全です。
| 置換前 | 置換後 | 理由 |
|---|---|---|
| 男 | 男性 | 表記ゆれを統一する |
| M | 男性 | 表記ゆれを統一する |
| 女 | 女性 | 表記ゆれを統一する |
| F | 女性 | 表記ゆれを統一する |
| 不明 | np.nan |
性別が不明な値として扱う |
ここでは、「不明」は性別がわからない値として扱うため、np.nanに変換します。
pd.NAも欠損値を表す値として使えますが、この記事ではColabで試しやすいようにnp.nanで統一します。細かな違いにはここでは深入りしません。
df_clean = df.copy()
gender_replace_dict = {
"男": "男性",
"M": "男性",
"女": "女性",
"F": "女性",
"不明": np.nan
}
df_clean["性別"] = df_clean["性別"].replace(gender_replace_dict)
df_clean[["顧客ID", "性別"]]
| 顧客ID | 性別 | |
|---|---|---|
| 0 | 1 | 男性 |
| 1 | 2 | 男性 |
| 2 | 3 | 男性 |
| 3 | 4 | 女性 |
| 4 | 5 | 女性 |
| 5 | 6 | 女性 |
| 6 | 7 | NaN |
| 7 | 8 | 男性 |
ここで行っている置換は、次のように整理できます。
| 元の値 | replace後 | 意味 |
|---|---|---|
| 男 | 男性 | 表記ゆれ修正 |
| M | 男性 | 表記ゆれ修正 |
| 女 | 女性 | 表記ゆれ修正 |
| F | 女性 | 表記ゆれ修正 |
| 不明 | NaN | 欠損値として扱う |
初心者のうちは、置換ルールをこのような表で確認してからコードを書くと、何を何に変えているのかが整理しやすくなります。
実際に、置換前と置換後を横並びで確認してみます。
表記ゆれを直す処理では、処理前→処理後を見比べると、意図した置換になっているか確認しやすくなります。
pd.DataFrame({
"顧客ID": df["顧客ID"],
"置換前_性別": df["性別"],
"置換後_性別": df_clean["性別"]
})
| 顧客ID | 置換前_性別 | 置換後_性別 | |
|---|---|---|---|
| 0 | 1 | 男性 | 男性 |
| 1 | 2 | 男 | 男性 |
| 2 | 3 | M | 男性 |
| 3 | 4 | 女性 | 女性 |
| 4 | 5 | 女 | 女性 |
| 5 | 6 | F | 女性 |
| 6 | 7 | 不明 | NaN |
| 7 | 8 | 男性 | 男性 |
置換後の件数を確認します。
dropna=Falseを指定すると、NaNも件数に含めて確認できます。
df_clean["性別"].value_counts(dropna=False)
| count | |
|---|---|
| 男性 | 4 |
| 女性 | 3 |
| NaN | 1 |
表記ゆれが整理され、「男性」「女性」「NaN」にまとまりました。
このように、replace()は単なる文字の置き換えだけでなく、集計しやすい形に値を整える前処理として使えます。
特定の列だけを置換する
初心者のうちは、DataFrame全体に対してまとめて置換するより、対象の列を指定して置換するほうが安全です。
たとえば、支払方法列に「カード」と「クレカ」が混ざっている場合を考えます。
どちらも同じ意味として扱うなら、「クレカ」を「カード」にそろえます。
df["支払方法"] = df["支払方法"].replace("クレカ", "カード")
このように列を指定しておくと、別の列に同じ文字があった場合でも、意図しない置換を避けやすくなります。
df_payment = df.copy()
df_payment["支払方法"] = df_payment["支払方法"].replace("クレカ", "カード")
df_payment["支払方法"].value_counts(dropna=False)
| count | |
|---|---|
| カード | 5 |
| 現金 | 2 |
| 不明 | 1 |
DataFrame全体にreplace()を使う場合
replace()は、列を指定せずにDataFrame全体へ使うこともできます。
たとえば、DataFrame内にある「不明」をすべてNaNにしたい場合は、次のように書けます。
df_all_replace = df.copy()
df_all_replace = df_all_replace.replace("不明", np.nan)
df_all_replace
| 顧客ID | 性別 | 年代 | 購入金額 | 来店日 | 支払方法 | |
|---|---|---|---|---|---|---|
| 0 | 1 | 男性 | 20代 | 1200 | 2025-04-01 | カード |
| 1 | 2 | 男 | 30代 | 3000 | 2025-04-02 | クレカ |
| 2 | 3 | M | NaN | 2500 | 未定 | 現金 |
| 3 | 4 | 女性 | 40代 | 1800 | 2025-04-05 | カード |
| 4 | 5 | 女 | 30代 | 4200 | なし | 現金 |
| 5 | 6 | F | – | 0 | 2025-04-07 | NaN |
| 6 | 7 | NaN | 20代 | 1500 | 2025-04-08 | クレカ |
| 7 | 8 | 男性 | なし | 2200 | – | カード |
この書き方は便利ですが、DataFrame全体に同じ値があると、意図していない列まで置換される可能性があります。
たとえば「不明」をすべてNaNにしたい場合は問題になりにくいですが、「0」や「なし」のように複数の意味で使われる値を一括置換するときは注意が必要です。
迷ったら、まずは次のように列を指定して置換すると安全です。
df["列名"] = df["列名"].replace(...)
どの列を変更しているのかが見えるため、あとから見直したときにも理解しやすくなります。
列を指定しておくと、他の列に同じ文字があった場合でも、意図しない置換を避けやすくなります。
複数列をまとめて指定したい場合は、次のようにDataFrameのreplace()に辞書を渡す書き方もあります。
df_column_dict = df.copy()
df_column_dict = df_column_dict.replace({
"性別": {"男": "男性", "M": "男性", "女": "女性", "F": "女性", "不明": np.nan},
"支払方法": {"クレカ": "カード", "不明": np.nan}
})
df_column_dict[["顧客ID", "性別", "支払方法"]]
| 顧客ID | 性別 | 支払方法 | |
|---|---|---|---|
| 0 | 1 | 男性 | カード |
| 1 | 2 | 男性 | カード |
| 2 | 3 | 男性 | 現金 |
| 3 | 4 | 女性 | カード |
| 4 | 5 | 女性 | 現金 |
| 5 | 6 | 女性 | NaN |
| 6 | 7 | NaN | カード |
| 7 | 8 | 男性 | カード |
複数列を一度に置換する書き方も便利ですが、初心者のうちはまず、次の形に慣れるのがおすすめです。
df["列名"] = df["列名"].replace(...)
どの列を置換しているのかが明確になるため、意図しない置換を避けやすくなります。
「不明」「-」「なし」を欠損値に変換する
replace()は、欠損値を埋めるためのメソッドではありません。
欠損値を埋める場合は、基本的にはfillna()を使います。
ただし、CSVには本来欠損として扱いたい値が、次のような文字列で入っていることがあります。
不明-なし未定
このような文字列をNaNに変換する場面では、replace()が役立ちます。
流れとしては、次の順番で考えるとわかりやすいです。
replace()で「不明」「-」「なし」などをNaNに変換するisnull().sum()で欠損数を確認する- 必要に応じて
fillna()で欠損値を補完する
df_missing = df.copy()
missing_values = ["不明", "-", "なし", "未定"]
df_missing["年代"] = df_missing["年代"].replace(missing_values, np.nan)
df_missing["来店日"] = df_missing["来店日"].replace(missing_values, np.nan)
df_missing[["顧客ID", "年代", "来店日"]]
| 顧客ID | 年代 | 来店日 | |
|---|---|---|---|
| 0 | 1 | 20代 | 2025-04-01 |
| 1 | 2 | 30代 | 2025-04-02 |
| 2 | 3 | NaN | NaN |
| 3 | 4 | 40代 | 2025-04-05 |
| 4 | 5 | 30代 | NaN |
| 5 | 6 | NaN | 2025-04-07 |
| 6 | 7 | 20代 | 2025-04-08 |
| 7 | 8 | NaN | NaN |
こちらも、置換前と置換後を横並びで確認してみます。
不明、-、なし、未定が、欠損値として扱えるNaNに変わっているかを確認します。
pd.DataFrame({
"置換前_年代": df["年代"],
"置換後_年代": df_missing["年代"],
"置換前_来店日": df["来店日"],
"置換後_来店日": df_missing["来店日"]
})
| 置換前_年代 | 置換後_年代 | 置換前_来店日 | 置換後_来店日 | |
|---|---|---|---|---|
| 0 | 20代 | 20代 | 2025-04-01 | 2025-04-01 |
| 1 | 30代 | 30代 | 2025-04-02 | 2025-04-02 |
| 2 | 不明 | NaN | 未定 | NaN |
| 3 | 40代 | 40代 | 2025-04-05 | 2025-04-05 |
| 4 | 30代 | 30代 | なし | NaN |
| 5 | – | NaN | 2025-04-07 | 2025-04-07 |
| 6 | 20代 | 20代 | 2025-04-08 | 2025-04-08 |
| 7 | なし | NaN | – | NaN |
NaNに変換できたかどうかは、isnull().sum()で確認できます。
df_missing[["年代", "来店日"]].isnull().sum()
| 0 | |
|---|---|
| 年代 | 3 |
| 来店日 | 3 |
ここでのポイントは、replace()でNaNに変換したあと、必要に応じてfillna()で補完するという順番です。
整理すると、役割は次のように分かれます。
| 処理 | 主に使うメソッド | 例 |
|---|---|---|
| 文字列の「不明」「-」「なし」を欠損値に変える | replace() |
"不明" → NaN |
すでにあるNaNを別の値で埋める |
fillna() |
NaN → "未回答" |
「不明」や「-」が文字列のまま残っていると、Pandasはそれを欠損値として扱ってくれません。
そのため、まずreplace()でNaNに変換し、その後にisnull()で確認したり、fillna()で補完したりします。
置換前後を確認する
replace()を使うときは、置換して終わりではなく、置換前後を確認することが大切です。
特に、表記ゆれを修正するときは、value_counts()で結果を比べるとわかりやすいです。
確認するときは、次の2つを見ます。
- 想定した値にまとまっているか
- 置換漏れや、意図しない
NaNが増えていないか
記事や実務メモに残す場合は、処理前と処理後を横並びにすると、何が変わったのかが伝わりやすくなります。
before = df["性別"].value_counts(dropna=False).rename("置換前")
after = df_clean["性別"].value_counts(dropna=False).rename("置換後")
pd.concat([before, after], axis=1)
| 置換前 | 置換後 | |
|---|---|---|
| 男性 | 2.0 | 4.0 |
| 男 | 1.0 | NaN |
| M | 1.0 | NaN |
| 女性 | 1.0 | 3.0 |
| 女 | 1.0 | NaN |
| F | 1.0 | NaN |
| 不明 | 1.0 | NaN |
| NaN | NaN | 1.0 |
置換前は「男性」「男」「M」が別々に集計されていました。
置換後は「男性」にまとまっているため、集計結果が見やすくなります。
このように、replace()はvalue_counts()とセットで使うと、表記ゆれの確認と修正がしやすくなります。
replace()とmap()の違い
replace()とよく比較されるのがmap()です。
どちらも値を変換できますが、初心者が注意したい大きな違いがあります。
| 比較 | replace() | map() |
|---|---|---|
| 主な用途 | 既存の値を一部置き換える | 対応表に従って値を変換する |
| 辞書にない値 | 基本的に元の値が残る | NaNになることがある |
| 表記ゆれ修正 | 使いやすい | 辞書漏れに注意 |
| 初心者向けの安全性 | 高め | 辞書にない値があると注意 |
表記ゆれを直すだけなら、まずはreplace()のほうが扱いやすいことが多いです。
一方で、「すべてのカテゴリを別のコードに変換する」のように、対応表に従って分類し直したい場合はmap()が向くこともあります。
s = pd.Series(["男性", "男", "M", "女性", "女", "F", "不明"])
replace_result = s.replace({"男": "男性", "M": "男性", "女": "女性", "F": "女性"})
map_result = s.map({"男": "男性", "M": "男性", "女": "女性", "F": "女性"})
pd.DataFrame({
"元の値": s,
"replaceの結果": replace_result,
"mapの結果": map_result
})
| 元の値 | replaceの結果 | mapの結果 | |
|---|---|---|---|
| 0 | 男性 | 男性 | NaN |
| 1 | 男 | 男性 | 男性 |
| 2 | M | 男性 | 男性 |
| 3 | 女性 | 女性 | NaN |
| 4 | 女 | 女性 | 女性 |
| 5 | F | 女性 | 女性 |
| 6 | 不明 | 不明 | NaN |
map()では、辞書に入っていない「男性」「女性」「不明」がNaNになっています。
これは便利な場面もありますが、表記ゆれを少しだけ直したいときには、思わぬ欠損値が増える原因にもなります。
そのため、初心者のうちは、表記ゆれ修正にはまずreplace()を使い、map()は「対応表にない値をNaNにしてもよい」と判断できる場面で使うと安全です。
pandas replace()が反映されない原因|代入していないのがよくある理由
replace()で初心者がつまずきやすいのは、「実行したのに元のDataFrameが変わらない」というケースです。
よくある原因は、置換結果を元の列に代入していないことです。
まずは、うまく反映されない例から確認します。
df_ng = df.copy()
# これは置換結果を表示しているだけで、df_ng自体は変更していません
df_ng["性別"].replace("男", "男性")
# 元のDataFrameを確認
df_ng[["顧客ID", "性別"]]
| 顧客ID | 性別 | |
|---|---|---|
| 0 | 1 | 男性 |
| 1 | 2 | 男 |
| 2 | 3 | M |
| 3 | 4 | 女性 |
| 4 | 5 | 女 |
| 5 | 6 | F |
| 6 | 7 | 不明 |
| 7 | 8 | 男性 |
元のDataFrameを変えたい場合は、次のように代入します。
df_ok = df.copy()
df_ok["性別"] = df_ok["性別"].replace("男", "男性")
df_ok[["顧客ID", "性別"]]
| 顧客ID | 性別 | |
|---|---|---|
| 0 | 1 | 男性 |
| 1 | 2 | 男性 |
| 2 | 3 | M |
| 3 | 4 | 女性 |
| 4 | 5 | 女 |
| 5 | 6 | F |
| 6 | 7 | 不明 |
| 7 | 8 | 男性 |
inplace=Trueを使う書き方もありますが、初心者には基本的に推奨しません。
理由は、元のDataFrameを直接変更するため、あとから見直したときに「どこで値が変わったのか」が追いにくくなることがあるからです。
初心者のうちは、次のように置換した結果を元の列に代入する書き方を基本にすると安心です。
df["列名"] = df["列名"].replace(置換前, 置換後)
この形なら、どの列を更新しているのかがコード上ではっきり見えます。
なお、非常に大きなデータを扱う場合は、メモリ効率の観点でinplace=Trueを検討することもあります。ただし、通常の学習や小〜中規模の分析では、まずは代入する書き方で十分です。
replace()を実行したのに結果が変わらないときは、まず代入しているかを確認してみましょう。
replace()とstr.replace()の違い|値全体か、文字列の一部か
replace()とstr.replace()は名前が似ていますが、使う場面が違います。
| やりたいこと | 使う方法 | 考え方 |
|---|---|---|
| 「男」という値を「男性」に置き換える | replace() |
値全体を別の値にする |
| 「1,200円」の「円」だけを消す | str.replace() |
文字列の一部を置き換える |
| 「商品A-001」から番号部分をまとめて処理する | str.replace() または replace(..., regex=True) |
パターンに合う部分を置き換える |
まずは、値そのものを置き換えるならreplace()、文字列の一部を置き換えるならstr.replace()と考えるとわかりやすいです。
price_df = pd.DataFrame({
"金額文字列": ["1,200円", "800円", "なし"]
})
price_df["円を削除"] = price_df["金額文字列"].str.replace("円", "", regex=False)
price_df
| 金額文字列 | 円を削除 | |
|---|---|---|
| 0 | 1,200円 | 1,200 |
| 1 | 800円 | 800 |
| 2 | なし | なし |
この例では、「1,200円」という値全体を別の値に変えているのではなく、文字列の中にある「円」だけを削除しています。
このような処理では、replace()よりもstr.replace()のほうが意図が伝わりやすくなります。
一方で、「なし」をNaNに変換したい場合は、値全体を置き換える処理なのでreplace()が向いています。
loc・where()・regex=Trueは補足として理解する
replace()は値そのものを置換するメソッドですが、似た場面でloc、where()、regex=Trueが出てくることがあります。
ここでは深入りせず、判断の目安だけ整理します。
条件に合う行だけ変更したいならloc
たとえば、「購入金額が0の行だけ欠損値として扱いたい」のように、条件で行を選んで変更するならlocが向いています。
df.loc[df["購入金額"] == 0, "購入金額"] = np.nan
これは「値が0ならどこでも置換する」というより、条件に合う行を指定して代入する考え方です。
条件によって残す・置き換えるならwhere()
where()は、条件を満たす値は残し、条件を満たさない値を別の値にする処理で使われます。
ただし、初心者のうちは、まずreplace()とlocの違いを理解してからで十分です。
regex=Trueは必要になってからでOK
replace()には、正規表現を使って置換するregex=Trueという指定もあります。
たとえば、商品コードの先頭にある「商品A-」「商品B-」のような部分をまとめて削除したい場合に使えます。
ただし、文字列の一部を単純に置き換えるだけなら、まずはstr.replace()を使うほうが読みやすいことが多いです。
replace(..., regex=True)は、文字列のパターンをまとめて処理したくなったときに覚えれば十分です。
sample_codes = pd.Series(["商品A-001", "商品B-002", "商品C-003"])
sample_codes.replace(r"商品[A-Z]-", "", regex=True)
| 0 | |
|---|---|
| 0 | 001 |
| 1 | 002 |
| 2 | 003 |
このコードでは、商品A-001、商品B-002、商品C-003から、先頭の「商品A-」「商品B-」「商品C-」にあたる部分を取り除いています。
ただし、正規表現は便利な一方で、初心者のうちは少し読みにくくなりがちです。
この記事の中心は、表記ゆれ修正や欠損値への変換で使う基本的なreplace()です。
まずは、次の2つの形に慣れることを優先すると十分です。
df["列名"].replace("置換前", "置換後")
df["列名"].replace({"A": "X", "B": "Y"})
regex=Trueは、文字列のパターンをまとめて処理したくなったタイミングで学べば問題ありません。
前処理の流れの中でreplace()を使うタイミング
replace()は単体で覚えるよりも、データ分析の流れの中で考えると理解しやすくなります。
たとえば、CSVを読み込んだあとに次のような流れで使います。
read_csv()でデータを読み込むhead()やinfo()で全体を確認するvalue_counts()で値のばらつきを確認するrename()で列名をわかりやすく整えるreplace()で表記ゆれや欠損扱いしたい値を整えるisnull()で欠損値を確認する- 必要に応じて
fillna()で欠損値を補完する astype()やto_datetime()で型を整えるgroupby()や可視化に進む
最後に、表記ゆれを直すと集計結果がどう見やすくなるかを確認します。
ここまでできると、replace()は単なる置換ではなく、集計の精度を上げるための前処理として理解しやすくなります。
df_flow = df.copy()
# 1. 表記ゆれを修正する
df_flow["性別"] = df_flow["性別"].replace({
"男": "男性",
"M": "男性",
"女": "女性",
"F": "女性",
"不明": np.nan
})
# 2. 欠損扱いしたい値をNaNに変換する
missing_values = ["不明", "-", "なし", "未定"]
df_flow["年代"] = df_flow["年代"].replace(missing_values, np.nan)
df_flow["来店日"] = df_flow["来店日"].replace(missing_values, np.nan)
df_flow["支払方法"] = df_flow["支払方法"].replace({"クレカ": "カード", "不明": np.nan})
# 3. 整えた後に性別ごとの購入金額を集計する
df_flow.groupby("性別", dropna=False)["購入金額"].mean()
| 購入金額 | |
|---|---|
| 女性 | 2000.0 |
| 男性 | 2225.0 |
| NaN | 1500.0 |
置換前の状態では、「男性」「男」「M」が別々のグループになってしまいます。
置換してから集計すると、同じ意味の値をまとめて扱えるため、分析結果が読みやすくなります。
このように、replace()は前処理の中で、確認と集計の間をつなぐ役割を持っています。
まとめ:replace()は値を整えて次の分析に進むための前処理
この記事では、pandas replace()の使い方を、値の置換・表記ゆれ修正・欠損値への変換という観点から解説しました。
ポイントを整理すると、次のとおりです。
replace()は、DataFrameやSeriesの中にある値そのものを置き換えるメソッド- 「男」「M」を「男性」にするような表記ゆれ修正に使いやすい
- 「不明」「-」「なし」などを
NaNに変換する前処理にも使える - 欠損値を埋める処理は
fillna()、列名変更はrename()、文字列の一部置換はstr.replace()と役割が違う map()は辞書にない値がNaNになることがあるため、表記ゆれ修正では注意が必要- 置換前後は
value_counts()、isnull()、処理前→処理後の横並び表で確認すると安心 - DataFrame全体に
replace()を使うこともできるが、初心者のうちは列を指定したほうが安全 inplace=Trueは初心者には基本的に推奨せず、まずは代入する書き方を基本にするとよい
replace()は、単なる文字の置き換えではなく、データを分析しやすい形に整えるための大切な前処理です。
表記ゆれを直したあとは、isnull()で欠損値を確認し、必要に応じてfillna()、astype()、to_datetime()、groupby()など次の処理へ進むと、分析の流れがつかみやすくなります。
次に読みたい関連記事
replace()を理解したら、次の記事とあわせて読むと、Pandasの前処理の流れがつかみやすくなります。
- Pandas DataFrame入門|作り方・基本操作をわかりやすく解説
- pandas value_counts()の使い方|件数集計・割合表示・欠損値の数え方を解説
- 欠損値を可視化して攻略!Pandas isnullとヒートマップ活用術
- pandas fillna()の使い方|欠損値を0・平均値・中央値・最頻値で埋める方法を初心者向けに解説
- pandas rename()の使い方|列名変更・一部だけ変更・反映されない原因を初心者向けに解説
- pandas astype()の使い方|文字列・数値への型変換とエラー対処を初心者向けに解説
前処理の順番で読むなら、value_counts()で値を確認し、replace()で表記ゆれを直し、isnull()やfillna()で欠損値を扱う流れがおすすめです。
pandas replace()は何をするメソッドですか?
replace()は、DataFrameやSeriesの中にある値そのものを、別の値に置き換えるメソッドです。たとえば、「男」を「男性」にしたり、「不明」をNaNにしたりするときに使います。
複数の値をまとめて置換できますか?
できます。リストを使って複数の値を同じ値に置き換えることもできますし、辞書を使って複数の置換ルールをまとめて書くこともできます。
特定の列だけreplace()できますか?
できます。初心者のうちは、df["列名"] = df["列名"].replace(...)のように、列を指定して置換する書き方がわかりやすく安全です。
「不明」や「-」を欠損値に変えるにはどうすればよいですか?
replace()でnp.nanに置き換えます。たとえば、df["列名"] = df["列名"].replace(["不明", "-", "なし"], np.nan)のように書けます。その後、isnull().sum()で確認すると安心です。
replace()とfillna()はどう使い分けますか?
replace()は「不明」や「-」のような文字列をNaNに変換するときに使えます。fillna()は、すでにNaNになっている欠損値を、0や平均値などで埋めるときに使います。
replace()とrename()は何が違いますか?
replace()は列の中に入っている値を置き換えます。rename()は列名や行名を変更します。列名を変えたい場合はrename()、値を変えたい場合はreplace()と考えるとわかりやすいです。
replace()とmap()は何が違いますか?
replace()は、指定した値を置き換え、指定していない値は基本的にそのまま残ります。一方、map()は辞書にない値がNaNになることがあるため、表記ゆれ修正では注意が必要です。
replace()とstr.replace()は何が違いますか?
replace()は値そのものを置き換えるときに使います。str.replace()は、文字列の一部だけを置き換えたいときに使います。たとえば、「1,200円」から「円」だけを削除する場合はstr.replace()が向いています。
regex=Trueは最初から覚える必要がありますか?
最初から無理に覚える必要はありません。まずは、値そのものを置き換える基本のreplace()に慣れることが大切です。文字列のパターンをまとめて処理したくなったときに、regex=Trueを学べば十分です。
inplace=Trueは使わないほうがよいですか?
初心者には、基本的にinplace=Trueは推奨しません。処理の流れが追いにくくなることがあるため、まずはdf["列名"] = df["列名"].replace(...)のように代入する書き方を基本にすると安心です。大きなデータではメモリ効率の観点で検討することもありますが、最初から使う必要はありません。
replace()を使ったのに元のDataFrameが変わらないのはなぜですか?
置換結果を元の列に代入していない可能性があります。基本的には、df["列名"] = df["列名"].replace(...)のように書くと、置換結果をDataFrameに反映できます。
コメント