Pandas Series map()で列の要素を置換する方法【完全ガイド】
Pandasでデータ処理を行う際、列の値を別の値に変換・置換したい場面は非常によくあります。Seriesのmap()メソッドを使えば、辞書や関数を使って効率的に要素の置換ができます。この記事では、map()メソッドの使い方を基本から応用まで、実践的なサンプルコードとともに詳しく解説します。
基本的な準備とサンプルデータの作成
まず、この記事で使用するサンプルDataFrameを作成しましょう。
import pandas as pd
import numpy as np
# サンプルデータの作成
df = pd.DataFrame({
'name': ['Alice', 'Bob', 'Charlie', 'David', 'Eve'],
'grade': ['A', 'B', 'A', 'C', 'B'],
'gender': ['F', 'M', 'M', 'M', 'F'],
'score': [85, 72, 90, 65, 78]
})
print(df)
このコードを実行すると、以下のようなDataFrameが作成されます:
name grade gender score
0 Alice A F 85
1 Bob B M 72
2 Charlie A M 90
3 David C M 65
4 Eve B F 78
map()メソッドの基本的な使い方
辞書を使った要素の置換
最もよく使われる方法は、辞書を使って値をマッピングすることです。
# 成績を数値に変換
grade_mapping = {'A': 4, 'B': 3, 'C': 2, 'D': 1}
df['grade_numeric'] = df['grade'].map(grade_mapping)
print(df[['grade', 'grade_numeric']])
この例では、文字の成績を対応する数値に変換しています。辞書のキーが元の値、バリューが変換後の値になります。
性別コードを日本語に変換
実用的な例として、性別コードを日本語に変換してみましょう。
# 性別を日本語に変換
gender_mapping = {'M': '男性', 'F': '女性'}
df['gender_jp'] = df['gender'].map(gender_mapping)
print(df[['gender', 'gender_jp']])
関数を使った要素の置換
ラムダ関数を使用
辞書だけでなく、関数を使って値を変換することもできます。
# スコアを評価に変換
df['evaluation'] = df['score'].map(lambda x: '優' if x >= 80 else '良' if x >= 70 else '可')
print(df[['score', 'evaluation']])
ラムダ関数を使うことで、複雑な条件分岐による変換も一行で記述できます。
定義済み関数を使用
より複雑なロジックの場合は、事前に関数を定義してから使用します。
# 複雑な変換ロジック
def categorize_score(score):
if score >= 90:
return 'S'
elif score >= 80:
return 'A'
elif score >= 70:
return 'B'
else:
return 'C'
df['category'] = df['score'].map(categorize_score)
print(df[['score', 'category']])
欠損値の処理
マッピング辞書にない値の処理
map()メソッドでは、マッピング辞書に存在しないキーはNaNになります。
# 不完全なマッピング辞書
incomplete_mapping = {'A': '優秀', 'B': '良好'} # Cがない
df['incomplete_result'] = df['grade'].map(incomplete_mapping)
print(df[['grade', 'incomplete_result']])
fillna()と組み合わせたデフォルト値の設定
マッピングされなかった値にデフォルト値を設定できます。
# デフォルト値を設定
df['grade_with_default'] = df['grade'].map(incomplete_mapping).fillna('その他')
print(df[['grade', 'grade_with_default']])
Seriesを使ったマッピング
別のSeriesをマッピング辞書として使用
Seriesオブジェクトをマッピング辞書として使用することもできます。
# マッピング用のSeries作成
mapping_series = pd.Series([4, 3, 2], index=['A', 'B', 'C'])
print("マッピングSeries:")
print(mapping_series)
# Seriesを使ったマッピング
df['grade_from_series'] = df['grade'].map(mapping_series)
print(df[['grade', 'grade_from_series']])
実践的な応用例
カテゴリデータの数値化
機械学習でよく行うカテゴリデータの数値化の例です。
# 部門コードを数値に変換
departments = pd.Series(['IT', 'HR', 'IT', 'Finance', 'HR'])
dept_mapping = {'IT': 1, 'HR': 2, 'Finance': 3}
dept_numeric = departments.map(dept_mapping)
print("部門の数値化:")
print(pd.DataFrame({'部門': departments, '数値': dept_numeric}))
日付データの変換
日付関連の変換もmap()で行えます。
# 月名を数値に変換
months = pd.Series(['Jan', 'Feb', 'Mar', 'Jan', 'Mar'])
month_mapping = {
'Jan': 1, 'Feb': 2, 'Mar': 3, 'Apr': 4,
'May': 5, 'Jun': 6, 'Jul': 7, 'Aug': 8,
'Sep': 9, 'Oct': 10, 'Nov': 11, 'Dec': 12
}
month_numeric = months.map(month_mapping)
print("月の数値化:")
print(pd.DataFrame({'月名': months, '月番号': month_numeric}))
複数条件による複雑なマッピング
# 成績とスコアの組み合わせによる評価
def complex_evaluation(row):
grade, score = row['grade'], row['score']
if grade == 'A' and score >= 85:
return '最優秀'
elif grade == 'A' or score >= 80:
return '優秀'
elif grade == 'B' or score >= 70:
return '良好'
else:
return '要改善'
# apply()と組み合わせて複雑な変換
df['complex_eval'] = df.apply(complex_evaluation, axis=1)
print(df[['grade', 'score', 'complex_eval']])
map()と類似メソッドの使い分け
map() vs replace() vs apply()
それぞれのメソッドの特徴と使い分けを説明します。
# map()の例
grade_map = {'A': 90, 'B': 80, 'C': 70}
mapped_result = df['grade'].map(grade_map)
# replace()の例
replaced_result = df['grade'].replace(grade_map)
# apply()の例
applied_result = df['grade'].apply(lambda x: grade_map.get(x, 0))
print("map()結果:")
print(mapped_result.head())
print("\nreplace()結果:")
print(replaced_result.head())
print("\napply()結果:")
print(applied_result.head())
パフォーマンスの比較
# パフォーマンス測定の例(大きなデータセット用)
large_series = pd.Series(['A', 'B', 'C'] * 10000)
mapping_dict = {'A': 1, 'B': 2, 'C': 3}
# 実際の測定は以下のように行います
# %timeit large_series.map(mapping_dict) # 最も高速
# %timeit large_series.replace(mapping_dict) # 中程度
# %timeit large_series.apply(lambda x: mapping_dict[x]) # 最も低速
エラーの回避とベストプラクティス
KeyErrorの回避
マッピング辞書にないキーでエラーが発生する場合の対処法:
def safe_mapping(value, mapping_dict, default=None):
"""安全なマッピング関数"""
return mapping_dict.get(value, default)
# 安全なマッピングの例
safe_result = df['grade'].map(lambda x: safe_mapping(x, grade_mapping, 'Unknown'))
print("安全なマッピング結果:")
print(safe_result)
大量データでのメモリ効率
# メモリ効率的なマッピング
def memory_efficient_mapping(series, mapping_dict):
"""メモリ効率を考慮したマッピング"""
# カテゴリ型に変換してからマッピング
categorical_series = series.astype('category')
return categorical_series.map(mapping_dict)
# 使用例(大量データの場合)
efficient_result = memory_efficient_mapping(df['grade'], grade_mapping)
print(f"データ型: {efficient_result.dtype}")
連鎖的なマッピング
複数段階の変換
複数のマッピングを連続して適用する場合:
# 第一段階:文字を数値に
stage1_mapping = {'A': 4, 'B': 3, 'C': 2}
stage1_result = df['grade'].map(stage1_mapping)
# 第二段階:数値を評価に
stage2_mapping = {4: '優秀', 3: '良好', 2: '普通'}
final_result = stage1_result.map(stage2_mapping)
print("連鎖マッピング結果:")
print(pd.DataFrame({
'元の成績': df['grade'],
'数値': stage1_result,
'最終評価': final_result
}))
まとめ
Pandas Seriesのmap()メソッドは、列の要素を効率的に置換・変換するための強力なツールです。この記事で紹介した手法を活用することで、様々なデータ変換ニーズに対応できます。
主なポイント:
- 辞書を使った簡単な値の置換が可能
- ラムダ関数や定義済み関数で複雑な変換ロジックを実装
fillna()との組み合わせで欠損値処理- Seriesオブジェクトもマッピング辞書として使用可能
replace()やapply()との使い分けが重要
データクリーニングや前処理において、map()メソッドは欠かせない機能です。用途に応じて適切な変換方法を選択し、効率的なデータ処理を実現しましょう。

