データ分析や機械学習のプロジェクトでは、Pandasを使ってデータフレームを操作することがよくあります。
データフレーム内の行ごとに処理を行いたい場合、Pandasのiterrows()メソッドが役立ちます。
今回は、iterrows()を使ってデータフレームの行をループ処理する方法を解説します。
具体的なコード例を交えながら基本的な使い方を説明し、さらにパフォーマンスの注意点や他の手法との比較も行います。こ
れを読むことで、iterrows()のメリットとデメリットを理解し、実際のデータ処理に活用できるようになるでしょう。
Contents
iterrows()の基本
Pandasのiterrows()メソッドは、データフレームの各行をループ処理するために使用されます。
このメソッドを使用することで、各行を1つずつ取り出し、そのデータを処理することができます。
特に、複雑な条件付きの処理や、行ごとに異なる操作を行いたい場合に便利です。
iterrows()の使い方
iterrows()は、データフレームの行を1つずつ返し、それぞれの行をタプル形式で取得します。
タプルの最初の要素は行のインデックス、2つ目の要素は行データがシリーズ(Series)形式で格納されています。
サンプルデータを作ります。
以下、コードです。
import pandas as pd
# Sample data
# Edit to Japan-style data
data = {
'Name': ['Taro', 'Hanako', 'Jiro'],
'Age': [25, 30, 35],
'City': ['Tokyo', 'Osaka', 'Nagoya']
}
# Create DataFrame
df = pd.DataFrame(data)
print(df)
以下、実行結果です。
Name Age City 0 Taro 25 Tokyo 1 Hanako 30 Osaka 2 Jiro 35 Nagoya
基本的な使用例を示します。
以下、コードです。
# iterrows()を使って各行を処理する
for index, row in df.iterrows():
print(f"Index: {index}")
print(f"Name: {row['Name']}, Age: {row['Age']}, City: {row['City']}")
print()
以下、実行結果です。
Index: 0 Name: Taro, Age: 25, City: Tokyo Index: 1 Name: Hanako, Age: 30, City: Osaka Index: 2 Name: Jiro, Age: 35, City: Nagoya
条件に基づくデータの更新
iterrows()を使用すると、特定の条件に基づいてデータを更新することができます。
例えば、年齢が30以上の人の都市名を大文字に変換する場合のコードは以下の通りです。
# 条件に基づいてデータを更新
for index, row in df.iterrows():
if row['Age'] >= 30:
df.at[index, 'City'] = row['City'].upper()
print(df)
以下、実行結果です。
Name Age City 0 Taro 25 Tokyo 1 Hanako 30 OSAKA 2 Jiro 35 NAGOYA
行ごとのデータの追加
新しい列を追加し、iterrows()を使って行ごとにデータを設定することも可能です。
例えば、年齢に基づいてカテゴリを追加する場合の例を示します。
以下、コードです。
# 新しい列の追加
df['Age Category'] = ''
# iterrows()を使って各行にデータを追加
for index, row in df.iterrows():
if row['Age'] < 30:
df.at[index, 'Age Category'] = 'Young'
else:
df.at[index, 'Age Category'] = 'Adult'
print(df)
以下、実行結果です。
Name Age City Age Category 0 Taro 25 Tokyo Young 1 Hanako 30 OSAKA Adult 2 Jiro 35 NAGOYA Adult
iterrows()の注意点
Pandasのiterrows()は便利なメソッドですが、特に大規模なデータセットに対して使用する場合、いくつかの注意点があります。
パフォーマンスの低下や、他の効率的な手法の存在などを理解することが重要です。
iterrows()の注意点と、それに代わる効率的な手法について詳しく説明します。
パフォーマンスの課題
iterrows()は、データフレームの各行を1つずつ処理するため、非常に直感的で理解しやすいメソッドです。
しかし、この方法はループ処理のため、データフレームが大きくなるとパフォーマンスが大幅に低下します。
Pythonのループは一般的に遅いため、大規模データセットには適していません。
以下に、iterrows()のパフォーマンスが問題となる例を示します。
import pandas as pd
import numpy as np
import time
# 大規模なデータフレームを作成
n_rows = 100000
data = {
'A': np.random.rand(n_rows),
'B': np.random.rand(n_rows)
}
df = pd.DataFrame(data)
# iterrows()のパフォーマンス計測
start_time = time.time()
for index, row in df.iterrows():
_ = row['A'] + row['B']
end_time = time.time()
print(f"iterrows() time: {end_time - start_time:.2f} seconds")
以下、実行結果です。
iterrows() time: 3.65 seconds
このコードを実行すると、処理時間がかなり長くなることがわかります。
大規模データに対してiterrows()を使用するのは非効率です。
apply()メソッド
apply()メソッドは、データフレームの各行または各列に対して関数を適用する方法です。
ベクトル化された操作を行うため、iterrows()よりも高速に処理できます。
以下、コードです。
# apply()を使った処理
start_time = time.time()
df['C'] = df.apply(lambda row: row['A'] + row['B'], axis=1)
end_time = time.time()
print(f"apply() time: {end_time - start_time:.2f} seconds")
以下、実行結果です。
apply() time: 0.68 seconds
この方法は、iterrows()よりも大幅に高速であり、大規模なデータセットに対して有効です。
ベクトル化された操作
Pandasはベクトル化された操作をサポートしており、これを利用することで処理をさらに高速化できます。
ベクトル化された操作は、NumPyを基盤としているため、高速で効率的です。
以下、コードです。
# ベクトル化された操作
start_time = time.time()
df['C'] = df['A'] + df['B']
end_time = time.time()
print(f"Vectorized operation time: {end_time - start_time:.2f} seconds")
以下、実行結果です。
Vectorized operation time: 0.00 seconds
この方法は最も高速で、特に大規模データセットに対して有効です。
itertuples()メソッド
itertuples()は、iterrows()の代わりに使用できるメソッドで、行をタプル形式で返します。
これにより、iterrows()よりも若干高速になります。
以下、コードです。
# itertuples()を使った処理
start_time = time.time()
for row in df.itertuples(index=True, name='Pandas'):
_ = row.A + row.B
end_time = time.time()
print(f"itertuples() time: {end_time - start_time:.2f} seconds")
以下、実行結果です。
itertuples() time: 0.06 seconds
itertuples()はiterrows()よりもメモリ効率が良く、処理速度も速いですが、ベクトル化された操作には劣ります。
まとめ
今回は、Pandasのiterrows()メソッドを中心に、データフレームの行操作についてお話ししました。
iterrows()は直感的で使いやすいメソッドですが、パフォーマンスの課題があるため、apply()メソッドやベクトル化された操作といった代替手法を理解し、適切に選択することが重要です。

