pandas の map と replace で値を置換する

データの値を別の値に置き換えたいことがあります。pandas では mapreplace を使って値を置換できます。それぞれ用途が異なるので、使い分けを理解しておきましょう。

map でマッピングする

map は Series の値を辞書やルールに従って変換します。

import pandas as pd

df = pd.DataFrame({
    'grade': ['A', 'B', 'C', 'A', 'B']
})

mapping = {'A': '', 'B': '', 'C': ''}
df['grade_jp'] = df['grade'].map(mapping)
print(df)

辞書に含まれない値があると NaN になります。

df = pd.DataFrame({
    'grade': ['A', 'B', 'D']  # D は辞書にない
})

mapping = {'A': '', 'B': '', 'C': ''}
df['grade_jp'] = df['grade'].map(mapping)
# D は NaN になる

map で関数を適用する

map には関数も渡せます。

df = pd.DataFrame({
    'name': ['alice', 'bob', 'charlie']
})

# 先頭を大文字に
df['name_cap'] = df['name'].map(str.capitalize)

# 独自の変換関数
df['name_upper'] = df['name'].map(lambda x: x.upper() + '!')

replace で置換する

replace は値を直接置換します。map と違い、マッピングにない値はそのまま残ります。

df = pd.DataFrame({
    'status': ['active', 'inactive', 'pending', 'active']
})

df['status'] = df['status'].replace({'active': 1, 'inactive': 0})
print(df)
# pending はそのまま残る

DataFrame 全体に対しても使えます。

df = pd.DataFrame({
    'A': [1, 2, 3],
    'B': [2, 3, 4]
})

# DataFrame 全体で 2 を 20 に置換
df = df.replace(2, 20)

複数の値を一度に置換する

replace はリストや辞書で複数の置換を指定できます。

# リストで指定(順番に対応)
df = df.replace([1, 2, 3], [10, 20, 30])

# 辞書で指定
df = df.replace({1: 10, 2: 20, 3: 30})

正規表現で置換する

regex=True を指定すると、正規表現でパターンマッチングして置換できます。

df = pd.DataFrame({
    'text': ['apple123', 'banana456', 'cherry789']
})

# 数字を削除
df['text'] = df['text'].replace(r'\d+', '', regex=True)

map と replace の使い分け

map

1 つの列の値を完全に変換する。辞書にない値は NaN になる。カテゴリ変数の変換に向いている。

replace

特定の値だけを置き換える。指定しない値はそのまま。部分的な修正や複数列への一括適用に向いている。

# map: すべての値を変換したい場合
grade_map = {'A': 4, 'B': 3, 'C': 2, 'D': 1, 'F': 0}
df['gpa'] = df['grade'].map(grade_map)

# replace: 一部の値だけ修正したい場合
df['status'] = df['status'].replace('Actve', 'Active')  # タイポ修正

データのクレンジングでは replace でタイポや表記ゆれを修正し、カテゴリのエンコーディングでは map で数値に変換する、という使い分けが一般的です。