0Pricing
Pandas & NumPy Academy · レッスン

要素単位の処理に使うmap()とapplymap()

map()でSeriesのすべての要素に、applymap()でDataFrameのすべてのセルに関数を適用します。

「要素単位の処理に使うmap()とapplymap()」はCoddyKit上の無料Pandas & NumPy Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはPandas & NumPy Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Pandas & NumPy Academyコースには全4レッスンが含まれています。

Series.map() の概要

Series.map() は、関数、辞書、または別の Series を Series の各要素に適用し、新しい Series を返します。複雑なオブジェクトを受け取れる apply() とは異なり、map() は常に個々のスカラー値を操作します。カテゴリ値のエンコード、対応表からのラベル検索、要素ごとの単純な変換に使う標準的なツールです。

import pandas as pd

codes = pd.Series(['N', 'S', 'E', 'N', 'W'])
region_names = {'N': 'North', 'S': 'South', 'E': 'East', 'W': 'West'}

names = codes.map(region_names)
print(names)

関数を使った map()

変換に対応表ではなくロジックが必要な場合は、関数(ラムダを含む)を map() に渡します。関数は一度に 1 つのスカラー値を受け取るため、他の行や列にはアクセスできません。単純な条件付きラベル割り当てでは、関数を使った map() はループより簡潔です。ただし、大きな Series では np.where() より遅くなります。

prices = pd.Series([5.0, 25.0, 80.0, 150.0])

category = prices.map(lambda p: 'budget' if p < 20 else 'mid' if p < 100 else 'premium')
print(category)

map() と replace() の比較

map() と replace() は、どちらも辞書を使って値を置き換えられます。重要な違いは、map() が辞書にない値に対して NaN を返す点です(後から fillna() を使う場合を除きます)。一方、replace() は一致しない値を変更せずに残します。特定の値だけを変更し、それ以外をそのまま維持したい場合は replace() を使います。

s = pd.Series(['A', 'B', 'C', 'D'])
map_dict = {'A': 'Alpha', 'B': 'Beta'}

print('map():', s.map(map_dict).tolist())      # C,D → NaN
print('replace():', s.replace(map_dict).tolist())  # C,D → unchanged

Series を使った map()(ラベル検索)

別の Series を対応表として map() に渡すこともできます。呼び出し元の Series の値をキーとして、引数の Series のインデックスから値を検索します。完全な merge() 呼び出しを使わずに対応表を結合できる簡潔な方法であり、キーをインデックスとするベクトル化された辞書検索のように動作します。

prices_lookup = pd.Series(
    [10.0, 25.0, 50.0],
    index=['SKU-001', 'SKU-002', 'SKU-003']
)

orders = pd.Series(['SKU-002', 'SKU-001', 'SKU-003', 'SKU-001'])
order_prices = orders.map(prices_lookup)
print(order_prices)

セル単位の操作に使う DataFrame.applymap()

DataFrame.applymap()(Pandas 2.1 以降では DataFrame.map() と呼ばれます)は、DataFrame の個々のセルすべてに関数を適用します。完全な列を受け取る apply(axis=0) とは異なり、applymap() は一度に 1 つのスカラー値を受け取ります。すべてのセルを一律に整形するときに便利です。たとえば、すべての数値セルを小数点以下 2 桁に丸めたり、すべての文字列セルを小文字に変換したりできます。

df = pd.DataFrame({
    'a': [1.234, 5.678, 9.012],
    'b': [3.456, 7.890, 2.345]
})

# Round every cell to 1 decimal place
df_rounded = df.applymap(lambda x: round(x, 1))
print(df_rounded)

文字列の整形に使う applymap()

文字列が混在する DataFrame のすべてのセルに、一貫した文字列整形を適用できます。たとえば、すべての値をタイトルケースにしたり、None を空文字列に変換したりできます。applymap(str.strip) を使えば、DataFrame 全体のすべてのセルから空白を 1 回の呼び出しで除去できます。これは、列を順番に処理して各列に .str.strip() を個別に適用するよりも、はるかに簡潔です。

df_str = pd.DataFrame({
    'name': [' Alice ', 'Bob  ', '  Carol'],
    'city': ['new york ', ' london', 'paris  ']
})

df_clean = df_str.applymap(str.strip)
print(df_clean)

通貨の整形に使う applymap()

レポート表示用に DataFrame を準備するときは、applymap() を使って数値セルを通貨形式の文字列に整形できます。これにより、基になるデータ型を変更せずに、数値を表示用の文字列に変換できます。この変換は最終出力のためだけに行います。整形した表を to_excel() または to_html() でエクスポートする前の最後の手順として適用してください。

revenue_table = pd.DataFrame({
    'North': [12300.0, 9800.0],
    'South': [7400.0, 11200.0]
}, index=['Q1', 'Q2'])

formatted = revenue_table.applymap(lambda x: f'${x:,.0f}')
print(formatted)

Pandas 2.1: applymap を map に名称変更

Pandas 2.1 では、Series.map() との一貫性を保つため、DataFrame.applymap() の名前が DataFrame.map() に変更されました。以前の applymap() も非推奨警告付きで引き続き動作します。実運用のコードでは、使用している Pandas のバージョンを確認し、2.1 以降であれば df.map(func) を使って、将来のリリースで非推奨警告が発生するのを避けてください。

import pandas as pd

print('Pandas version:', pd.__version__)

# Forward-compatible pattern:
if hasattr(pd.DataFrame, 'map'):
    df_clean = df_str.map(str.strip)  # Pandas 2.1+
else:
    df_clean = df_str.applymap(str.strip)  # Pandas < 2.1

print(df_clean)

カテゴリ特徴量のエンコードに使う map()

機械学習モデルには数値入力が必要なため、カテゴリ列をエンコードする必要があります。整数エンコード用の辞書と map() を使って、DataFrame をモデルに渡す前にカテゴリを順序尺度の数値へ変換します。自然な順序を持たない名義尺度のカテゴリでは、代わりに pd.get_dummies() または scikit-learn の OneHotEncoder を使うことをおすすめします。

size_order = {'small': 0, 'medium': 1, 'large': 2, 'enterprise': 3}

df['size_encoded'] = df['order_size'].map(size_order)
print(df[['order_size', 'size_encoded']])

複数段階の検索で map() を連結する

2 段階の検索が必要な場合は、2 回の map() 呼び出しを連結します。まずコードを中間キーに変換し、次に中間キーを最終ラベルに変換します。たとえば、商品 SKU をカテゴリコードに変換してから、カテゴリコードをカテゴリ名に変換します。2 回の map() 呼び出しを連結する方が、入れ子の辞書や、別の merge に続く merge よりも簡潔です。

sku_to_cat_code = {'SKU-001': 'C1', 'SKU-002': 'C2', 'SKU-003': 'C1'}
cat_code_to_name = {'C1': 'Electronics', 'C2': 'Apparel'}

skus = pd.Series(['SKU-001', 'SKU-002', 'SKU-003'])
cat_names = skus.map(sku_to_cat_code).map(cat_code_to_name)
print(cat_names)

map による要素単位の null 処理

map(func) を使うと、NaN 値に対しても関数が呼び出されるため、関数が None を処理できない場合は TypeError が発生することがあります。pd.isna(x) を使った null チェックで関数をラップするか、map() の na_action='ignore' パラメータを使って NaN 値をスキップしてください。後者では関数を呼び出さず、出力でも NaN のまま維持できます。

s = pd.Series([1.0, None, 3.0, None, 5.0])

# na_action='ignore' skips NaN values
result = s.map(lambda x: x * 2, na_action='ignore')
print(result)

理解度チェック

このレッスンで学んだデータ分析の概念について理解度を確認しましょう。

レッスンのまとめ

このレッスンでは、関数や辞書を使ったスカラー値の検索に Series.map() を使う方法、すべての列にまたがるセル単位の整形に DataFrame.applymap()/map() を使う方法、そして一致しない値を処理する際の map() と replace() の違いを学びました。次は、読みやすい変換パイプラインを実現する pipe() によるメソッドチェーンを見ていきます。

よくある質問

「要素単位の処理に使うmap()とapplymap()」レッスンは無料ですか?

はい。「要素単位の処理に使うmap()とapplymap()」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Pandas & NumPy Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Pandas & NumPy Academyコースには全4レッスンが含まれています。

「要素単位の処理に使うmap()とapplymap()」で何を学びますか?

map()でSeriesのすべての要素に、applymap()でDataFrameのすべてのセルに関数を適用します。 ブラウザで直接実行するハンズオンコードでPandas & NumPy Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Pandas & NumPy Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのPandas & NumPy Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。

「要素単位の処理に使うmap()とapplymap()」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このPandas & NumPy Academyレッスンでコードを書いて実行できますか?

はい。すべてのPandas & NumPy Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 列と行へのapply()
  2. GroupByでのapply()
  3. 要素単位の処理に使うmap()とapplymap()
  4. pipe()によるメソッドチェーン
← Pandas & NumPy Academyに戻る