Pandas は Python のデータ操作フレームワークとして非常によく知られています。
多くの場合、データに対して反復処理を行いたいと思うかもしれません。
このチュートリアルでは、Pandas の DataFrame
内の行を繰り返し処理する方法を見ていきます。
Pandas に慣れていない場合は、初心者向けのチュートリアルを参照してください。
慣れてきたら、DataFrameを反復処理する3つの主な方法を見てみましょう。
items()
iterrows()
itertuples()
items()によるDataFrameの反復処理
架空の人物のデータを含む DataFrame
を設定してみましょう。
import pandas as pd
df = pd.DataFrame({
'first_name': ['John', 'Jane', 'Marry', 'Victoria', 'Gabriel', 'Layla'],
'last_name': ['Smith', 'Doe', 'Jackson', 'Smith', 'Brown', 'Martinez'],
'age': [34, 29, 37, 52, 26, 32]},
index=['id001', 'id002', 'id003', 'id004', 'id005', 'id006'])
ここでは、id を DataFrame
のインデックスとして使用していることに注意してください。
それでは、DataFrame
がどのように見えるか見てみましょう。
print(df.to_string())
first_name last_name age
id001 John Smith 34
id002 Jane Doe 29
id003 Marry Jackson 37
id004 Victoria Smith 52
id005 Gabriel Brown 26
id006 Layla Martinez 32
さて、この DataFrame
に対して繰り返し処理を行うには、 items()
関数を使用します。
df.items()
これはジェネレータを返します。
<generator 0x7f3c064c1900="" at="" dataframe.items="" object=""
これを使用して、 col_name
と data
のペアを生成することができます。
これらのペアは、カラム名とそのカラムのすべてのデータ行を含むことになります。
それでは、カラム名とそのデータをループしてみましょう。
for col_name, data in df.items():
print("col_name:",col_name, "
data:",data)
この結果、次のようになります。
col_name: first_name
data:
id001 John
id002 Jane
id003 Marry
id004 Victoria
id005 Gabriel
id006 Layla
Name: first_name, dtype: object
col_name: last_name
data:
id001 Smith
id002 Doe
id003 Jackson
id004 Smith
id005 Brown
id006 Martinez
Name: last_name, dtype: object
col_name: age
data:
id001 34
id002 29
id003 37
id004 52
id005 26
id006 32
Name: age, dtype: int64
これで、各カラムのすべての行に対して反復処理が行われました。
index カラムは反復処理の間、同じままであることに注意してください。
これは、値に関連するインデックスであるためです。
インデックスを定義しない場合、Pandasはインデックスカラムを適切に列挙します。
Pythonのリストと同じように、 data
にインデックス番号を渡すことで、特定の行を表示することもできます。
for col_name, data in df.items():
print("col_name:",col_name, "
data:",data[1])
リストのインデックスはゼロインデックスなので、 data[1]
は2行目を参照することに注意してください。
このような出力が表示されます。
col_name: first_name
data: Jane
col_name: last_name
data: Doe
col_name: age
data: 29
また、data
にインデックスの値を渡すこともできます。
for col_name, data in df.items():
print("col_name:",col_name, "
data:",data['id002'])
出力は前と同じになります。
col_name: first_name
data: Jane
col_name: last_name
data: Doe
col_name: age
data: 29
iterrows()によるDataFrameのイテレーション
df.items()が列単位で行を反復し、各列ごとにサイクルを回すのに対して、
iterrows()` を使用するとインデックスの行データ全体を取得することができます。
それでは、iterrows()
を使って行を反復してみましょう。
for i, row in df.iterrows():
print(f"Index: {i}")
print(f"{row}
")
forループの中で、 i
はインデックスのカラムを表し (このDataFrameのインデックスは id001
から id006
まで)、 row
にはそのインデックスのすべてのカラムのデータが格納されます。
出力はこのようになります。
Index: id001
first_name John
last_name Smith
age 34
Name: id001, dtype: object
Index: id002
first_name Jane
last_name Doe
age 29
Name: id002, dtype: object
Index: id003
first_name Marry
last_name Jackson
age 37
Name: id003, dtype: object
...
同様に、あるカラムの行を繰り返し処理することもできます。
単に、 row
にインデックス番号やカラム名を渡すだけです。
例えば、次のように行の最初の列を選択的に表示することができます。
for i, row in df.iterrows():
print(f"Index: {i}")
print(f"{row['0']}")
あるいは
for i, row in df.iterrows():
print(f"Index: {i}")
print(f"{row['first_name']}")
どちらもこのような出力になります。
Index: id001
John
Index: id002
Jane
Index: id003
Marry
Index: id004
Victoria
Index: id005
Gabriel
Index: id006
Layla
itertuples()によるDataFramesの反復処理
itertuples()` 関数は、タプルの行の値を生成するジェネレータも返します。
これを試してみましょう。
for row in df.itertuples():
print(row)
Pythonのシェルでこのように表示されます。
Pandas(Index='id001', first_name='John', last_name='Smith', age=34)
Pandas(Index='id002', first_name='Jane', last_name='Doe', age=29)
Pandas(Index='id003', first_name='Marry', last_name='Jackson', age=37)
Pandas(Index='id004', first_name='Victoria', last_name='Smith', age=52)
Pandas(Index='id005', first_name='Gabriel', last_name='Brown', age=26)
Pandas(Index='id006', first_name='Layla', last_name='Martinez', age=32)
itertuples()メソッドは2つの引数を持っています。
index と name
です。
indexパラメータを
False` に設定することで、インデックスカラムを表示しないようにすることができます。
for row in df.itertuples(index=False):
print(row)
タプルのインデックスが表示されなくなります。
Pandas(first_name='John', last_name='Smith', age=34)
Pandas(first_name='Jane', last_name='Doe', age=29)
Pandas(first_name='Marry', last_name='Jackson', age=37)
Pandas(first_name='Victoria', last_name='Smith', age=52)
Pandas(first_name='Gabriel', last_name='Brown', age=26)
Pandas(first_name='Layla', last_name='Martinez', age=32)
すでにお気づきのように、このジェネレータはデフォルトで Pandas
という名前の名前付きタプルを生成します。
これを変更するには、 name
パラメータに People
という引数を渡します。
好きな名前を選ぶことができますが、データに関連する名前を選ぶのが常にベストです。
for row in df.itertuples(index=False, name='People'):
print(row)
これで、出力は次のようになります。
People(first_name='John', last_name='Smith', age=34)
People(first_name='Jane', last_name='Doe', age=29)
People(first_name='Marry', last_name='Jackson', age=37)
People(first_name='Victoria', last_name='Smith', age=52)
People(first_name='Gabriel', last_name='Brown', age=26)
People(first_name='Layla', last_name='Martinez', age=32)
Pandasによる反復処理性能
Pandasの公式ドキュメントでは、イテレーションは遅い処理であると警告しています。
もし、データを修正するために DataFrame
に対して反復処理を行うのであれば、ベクトル化の方が早いでしょう。
Pandas は行のデータのコピーを返し、参照は返さないので、すべてのデータが実際に変更されるわけではありません。
小さなデータセットであれば、 to_string()
メソッドを使ってすべてのデータを表示することができます。
多くの列や行を持つ大きなデータセットの場合は、 head(n)
や tail(n)
メソッドを使うと、DataFrame の最初の n
行を出力することができます(n
のデフォルト値は 5 です)。
速度比較
各メソッドの速度を測定するために、我々はそれらを1000回実行し、平均実行時間を返す関数にラップしました。
これらのメソッドをテストするために、より良い比較データを提供し、一般的なユースケースをカバーするために、 print()
と list.append()
の両方の関数を使用することにします。
公平に勝者を決めるために、DataFrameに対して繰り返し処理を行い、ループごとに1つの値だけをprintまたはappendするようにします。
各メソッドの戻り値はこんな感じです。
例えば、items()
は列ごとに循環させますが、items()
は、列ごとに循環させます。
('first_name',
id001 John
id002 Jane
id003 Marry
id004 Victoria
id005 Gabriel
id006 Layla
Name: first_name, dtype: object)
iterrows()` は、特定の行のすべての列のデータを提供します。
('id001',
first_name John
last_name Smith
age 34
Name: id001, dtype: object)
そして最後に、iteruples()
の 1 つの行は以下のようになります。
Pandas(Index='id001', first_name='John', last_name='Smith', age=34)
以下は、平均的な結果を秒単位で表したものです。
メソッド|スピード(秒)|テスト関数|アイテム() | ||
アイテム() | 1.349279541666571 | プリント() |
iterrows() | 3.4104003086661883 | print() |
itertuples() | 0.41232967500279 | print() |
| — | — | — |
| 方法|速度(s)| テスト関数(t)
| items() | 0.006637570998767235 | append() | 0.006637570998767235 | append() | 0.006637570998767235
| iterrows() | 0.5749766406661365 | append()
| itertuples() | 0.3058610513350383 | append()
値のプリントは一般的にアペンドより多くの時間とリソースを必要とし、我々の例も例外ではありません。
print()と組み合わせた場合は
itertuples()がより良いパフォーマンスを示す一方で、
append()に使用した場合は
items()メソッドが劇的に他のメソッドを上回り、
iterrows()` はそれぞれの比較で最後に残りました。
これらのテスト結果は、OSや環境、計算機資源などの他の要素に大きく依存することに注意してください。
また、データのサイズも結果に影響を与えます。
結論
Pandasの3つのメソッド、 items()
, iterrows()
, itertuples()
を使ってDataFrameを反復処理する方法について学びました。
あなたのデータや好みに応じて、これらのメソッドのいずれかをプロジェクトで使用することができます。
を使用します。