Pandas apply 徹底解説: 効率的なデータ操作をマスターしよう!
Pythonでデータ分析を行う際、Pandasは欠かせないツールです。特に、データフレーム内の各要素や行、列に対して独自の処理を適用したい場面は頻繁にあります。そんな時に役立つのが、Pandasの強力なメソッド**apply**です。
この記事では、Pandas applyの基本的な使い方から、効率的なデータ操作を可能にする応用テクニックまで、徹底的に解説します。
Pandas applyってどんなもの?
Pandasのapplyメソッドは、DataFrameの各行または各列、あるいはSeriesの各要素に、ユーザー定義の関数やラムダ式を適用するための機能です。これにより、Pythonのループ処理を書くよりも簡潔に、そして多くの場合で高速にデータ加工や変換を実行できます。
applyでできること
-
行ごと・列ごとの複雑な変換: 複数の列の値を組み合わせて新しい列を作成したり、行全体に基づいて条件分岐を行ったりできます。
-
要素ごとの処理: Seriesの各要素に対して、文字列操作、数値計算、データ型変換などを適用できます。
-
外部ライブラリとの連携: 特定のライブラリの関数をPandasデータに直接適用できます。
なぜapplyを選ぶべきか?
applyを使うことには、以下のようなメリットがあります。
-
コードの簡潔性: Pythonの
forループと比較して、よりPythonicで読みやすいコードを書くことができます。 -
処理の高速化: 内部的に最適化されており、多くの場合で純粋なPythonのループよりも高速に動作します。特にNumPyの関数やC拡張で実装された関数と組み合わせることで、パフォーマンスをさらに向上させることができます。
-
高い柔軟性: 組み込み関数、カスタム関数、ラムダ式など、あらゆる種類の関数を適用できるため、非常に幅広いデータ操作に対応できます。
applyを始めるための準備
1. ライブラリのインポートとデータの準備
applyを使うためには、Pandasライブラリをインポートし、操作したいデータがDataFrame形式で用意されている必要があります。
import pandas as pd
# サンプルデータフレームの作成
data = {
'Name': ['Alice', 'Bob', 'Charlie', 'David', 'Eve'],
'Score1': [85, 92, 78, 95, 88],
'Score2': [70, 80, 90, 75, 82],
'Category': ['A', 'B', 'A', 'B', 'C']
}
df = pd.DataFrame(data)
print("--- 元のデータフレーム ---")
print(df)
print("\n")
applyの基本的な使い方
applyメソッドは、Seriesに対して使う場合と、DataFrameに対して使う場合で少し動作が異なります。
1. Seriesに対するapply
Seriesの各要素に関数を適用します。
例1: 数値列の各要素を2倍にする
# 'Score1'列の各要素を2倍にする
df['Score1_Doubled'] = df['Score1'].apply(lambda x: x * 2)
print("--- 'Score1_Doubled'列を追加 (Series.apply) ---")
print(df[['Name', 'Score1', 'Score1_Doubled']])
print("\n")
例2: 文字列を大文字にする
# 'Category'列の各要素を大文字にする
df['Category_Upper'] = df['Category'].apply(str.upper)
print("--- 'Category_Upper'列を追加 (Series.apply) ---")
print(df[['Name', 'Category', 'Category_Upper']])
print("\n")
2. DataFrameに対するapply
DataFrameに対してapplyを使う場合、デフォルトでは列ごとに関数が適用されます。axis=1を指定すると行ごとに適用されます。
例3: 各列の合計値を計算 (列ごと、デフォルト)
# 数値列の合計値を計算
# axis=0がデフォルトなので、列ごとに関数が適用される
column_sums = df[['Score1', 'Score2']].apply(sum)
print("--- 各数値列の合計 (DataFrame.apply, axis=0) ---")
print(column_sums)
print("\n")
例4: 各行のScore1とScore2の合計を計算 (行ごと)
# 各行のScore1とScore2を合計して新しい列を作成
# axis=1を指定すると、行ごとにラムダ関数が適用される
df['Total_Score'] = df.apply(lambda row: row['Score1'] + row['Score2'], axis=1)
print("--- 'Total_Score'列を追加 (DataFrame.apply, axis=1) ---")
print(df[['Name', 'Score1', 'Score2', 'Total_Score']])
print("\n")
例5: 複数の列を条件に評価して新しいカテゴリを作成 (行ごと、カスタム関数)
# Score1が90以上かつScore2が80以上なら'Excellent'、そうでなければ'Good'
def categorize_performance(row):
if row['Score1'] >= 90 and row['Score2'] >= 80:
return 'Excellent'
else:
return 'Good'
df['Performance'] = df.apply(categorize_performance, axis=1)
print("--- 'Performance'列を追加 (DataFrame.apply, 行ごとカスタム関数) ---")
print(df[['Name', 'Score1', 'Score2', 'Performance']])
print("\n")
applyのパフォーマンスに関する注意点
applyは非常に柔軟で便利ですが、場合によってはPythonのforループよりも遅くなることがあります。特に、大規模なデータに対して複雑なPython関数をapplyで呼び出す場合、パフォーマンスが問題になることがあります。
-
高速な代替手段を検討:
-
ベクトル化: NumPyの配列操作やPandasのSeries/DataFrameの組み込みメソッド(例:
df['col'] * 2、df['col'].str.contains()など)は、C言語レベルで最適化されているため、最も高速です。可能な限りベクトル化された操作を優先しましょう。 -
map(): Seriesの要素を別の値にマッピングするだけなら、applyよりもmap()が推奨される場合があります。 -
agg()/transform(): 集計や変換に特化した機能で、applyよりも高速な場合があります。 -
Cython / Numba: 非常に複雑でパフォーマンスが要求される場合は、これらのツールでPythonコードを最適化することも検討できます。
-
しかし、ほとんどのデータ分析タスクでは、applyは十分なパフォーマンスを提供し、コードの可読性を高める点で非常に有用です。
まとめ
この記事では、Pandasの強力なメソッドapplyについて、その特徴、SeriesとDataFrameに対する基本的な使い方、そして行ごと・列ごとのカスタム関数の適用例を徹底的に解説しました。
applyを使いこなすことで、Pandasのデータフレームに対する柔軟で効率的なデータ操作が可能になります。データ加工、特徴量エンジニアリング、条件に基づく新しい列の作成など、あなたのデータ分析ワークフローにおいてapplyは欠かせないツールとなるでしょう。
■プロンプトだけでオリジナルアプリを開発・公開してみた!!
■AI時代の第一歩!「AI駆動開発コース」はじめました!
テックジム東京本校で先行開始。
■テックジム東京本校
「武田塾」のプログラミング版といえば「テックジム」。
講義動画なし、教科書なし。「進捗管理とコーチング」で効率学習。
より早く、より安く、しかも対面型のプログラミングスクールです。
<短期講習>5日で5万円の「Pythonミニキャンプ」開催中。
<月1開催>放送作家による映像ディレクター養成講座
<オンライン無料>ゼロから始めるPython爆速講座

