Pandas DataFrameの行を繰り返し処理する方法

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_namedata のペアを生成することができます。

これらのペアは、カラム名とそのカラムのすべてのデータ行を含むことになります。

それでは、カラム名とそのデータをループしてみましょう。

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を反復処理する方法について学びました。

あなたのデータや好みに応じて、これらのメソッドのいずれかをプロジェクトで使用することができます。

を使用します。

タイトルとURLをコピーしました