【Pandas関数適用術】map, apply, applymapを使いこなしてデータ処理を効率化しよう!🚀


 

Pandasでデータ分析を行う際、DataFrameやSeriesの個々の要素、行、または列に対して特定の処理を適用したい場面は頻繁にあります。そんな時に役立つのが、**mapapplyapplymap**という3つのメソッドです。これらを適切に使い分けることで、ループ処理を書くことなく、より効率的かつ簡潔にデータ操作を行うことができます。この記事では、それぞれのメソッドの特性と使い方を、短いサンプルコードと丁寧な解説でご紹介します。


 

map, apply, applymapとは?なぜ使い分けるのか?

 

これらのメソッドは、Pandasオブジェクト(SeriesやDataFrame)に関数を適用するためのツールですが、適用範囲や得意な処理が異なります。

  • map: Seriesの各要素に対して関数を適用したり、値を置換したりする際に使います。

  • apply: SeriesまたはDataFrameの行全体、または列全体に対して関数を適用する際に使います。最も汎用性が高いメソッドです。

  • applymap: DataFrameの各要素に対して関数を適用する際に使います。

これらを使い分けることで、コードの可読性を高め、処理速度を最適化できます。


 

mapメソッドの使い方(Seriesの要素向け)

 

mapは主にSeriesで使われ、各要素を変換したり、辞書やSeriesを使って値をマッピング(置換)したりするのに非常に便利です。

 

関数を適用して各要素を変換する

 

Seriesの各要素にシンプルな関数を適用したい場合に便利です。

Python
 
import pandas as pd

s = pd.Series([1, 2, 3, 4])
print("オリジナルSeries:\n", s)

# 各要素を2倍にする
s_mapped = s.map(lambda x: x * 2)
print("\nmapで2倍にしたSeries:\n", s_mapped)

解説:

lambda x: x * 2という匿名関数がsの各要素(1, 2, 3, 4)に適用され、新しいSeriesが生成されます。

 

辞書を使って値を置換する(マッピング)

 

特定の値を別の値に置き換えたい場合に非常に効率的です。

Python
 
s_str = pd.Series(['apple', 'banana', 'apple', 'orange'])
print("\nオリジナルSeries (文字列):\n", s_str)

# 辞書を使って値を置換
mapping = {'apple': 'リンゴ', 'banana': 'バナナ'}
s_mapped_dict = s_str.map(mapping)
print("\nmapで辞書置換したSeries:\n", s_mapped_dict)

解説:

s_strの要素がmapping辞書のキーと一致すれば、対応する値に置換されます。辞書にない’orange’はNaNになります。


 

applyメソッドの使い方(行・列全体向け)

 

applyはSeriesとDataFrameの両方で使え、行または列全体に関数を適用する最も汎用的なメソッドです。

 

Seriesに行(列)に関数を適用する

 

Seriesではmapと同様に要素に適用されますが、より複雑な処理も可能です。

Python
 
s = pd.Series([1, 2, 3, 4])

# Seriesの合計を計算 (applyでも可能だが、s.sum()の方が一般的)
s_apply_sum = s.apply(lambda x: x * 2) # この場合mapと同じ
print("\napplyで2倍にしたSeries:\n", s_apply_sum)

 

DataFrameの行または列に関数を適用する

 

axis引数を使って、行方向(axis=1)または列方向(axis=0、デフォルト)に関数を適用します。

Python
 
df = pd.DataFrame({
    'A': [10, 20, 30],
    'B': [1, 2, 3]
})
print("\nオリジナルDataFrame:\n", df)

# 列ごとに合計を計算 (axis=0がデフォルト)
df_col_sum = df.apply(lambda col: col.sum(), axis=0)
print("\napplyで列合計を計算したSeries:\n", df_col_sum)

# 行ごとに合計を計算 (axis=1)
df_row_sum = df.apply(lambda row: row.sum(), axis=1)
print("\napplyで行合計を計算したSeries:\n", df_row_sum)

解説:

  • axis=0(列方向):lambda col: col.sum()が’A’列、’B’列のSeriesそれぞれに適用され、その合計値が計算されます。

  • axis=1(行方向):lambda row: row.sum()が各行のSeriesに適用され、その行の合計値が計算されます。

 

複数の列に条件付きで関数を適用する

 

applyを使うと、複数の列を考慮した複雑な条件処理も行えます。

Python
 
df_multi = pd.DataFrame({
    'Score1': [70, 85, 90],
    'Score2': [60, 95, 80],
    'Passed': [True, False, True]
})
print("\nオリジナルDataFrame (条件付き):\n", df_multi)

# Score1が80以上かつScore2が70以上なら'Excellent'、そうでなければ'Good'と評価
def evaluate_scores(row):
    if row['Score1'] >= 80 and row['Score2'] >= 70:
        return 'Excellent'
    else:
        return 'Good'

df_multi['Evaluation'] = df_multi.apply(evaluate_scores, axis=1)
print("\napplyで評価列を追加したDataFrame:\n", df_multi)

解説:

evaluate_scores関数は各行を受け取り、その行の’Score1’と’Score2’の値に基づいて評価を返します。この関数がaxis=1で行ごとに適用され、新しい’Evaluation’列が作成されます。


 

applymapメソッドの使い方(DataFrameの要素向け)

 

applymapは、DataFrameの各要素すべてに同じ関数を適用したい場合に特化しています。SeriesのmapのDataFrame版と考えるとわかりやすいです。

Python
 
df_elem = pd.DataFrame({
    'X': [1.1, 2.2, 3.3],
    'Y': [4.4, 5.5, 6.6]
})
print("\nオリジナルDataFrame (applymap用):\n", df_elem)

# 各要素を整数に変換
df_elem_int = df_elem.applymap(lambda x: int(x))
print("\napplymapで各要素を整数に変換したDataFrame:\n", df_elem_int)

解説:

lambda x: int(x)という匿名関数が、DataFramedf_elemのすべての要素に適用され、浮動小数点数が整数に変換されています。


 

どのメソッドを選ぶべきか?使い分けのポイント

 

メソッド 適用範囲 主な用途 注意点
map Seriesの各要素 – 各要素の変換<br>- 辞書やSeriesでの値のマッピング DataFrameには直接適用できない
apply Series全体 or DataFrameの行/列全体 – 行/列ごとの集計(合計、平均など)<br>- 行/列全体を使った複雑な条件処理 各要素への適用はapplymapの方が明確な場合がある
applymap DataFrameの各要素 – DataFrame全体の要素単位の変換(データ型変換、フォーマット変更など) Seriesには直接適用できない<br>Pythonのループに近い処理になるため、大規模データでは速度に注意

💡 ヒント:

  • Seriesの個々の要素を変換するなら map

  • DataFrameの全ての個々の要素を変換するなら applymap

  • DataFrameの行または列全体を一つの単位として処理するなら apply


 

まとめ

 

Pandasのmapapplyapplymapメソッドは、データ操作を効率化するための強力なツールです。それぞれの適用範囲と特性を理解し、適切に使い分けることで、よりクリーンでパフォーマンスの高いコードを書くことができます。データクレンジング、特徴量エンジニアリング、集計など、様々なデータ分析の場面でこれらのメソッドをぜひ活用してみてください。