パンダでデータフレームをループする最も効率的な方法は何ですか?[複製]

340
Muppet 2011-10-21 04:46.

データフレーム内の財務データに対して、独自の複雑な操作を順番に実行したいと思います。

たとえば、私はから取られた次MSFT CSVファイル使用していますヤフーファイナンス:

Date,Open,High,Low,Close,Volume,Adj Close
2011-10-19,27.37,27.47,27.01,27.13,42880000,27.13
2011-10-18,26.94,27.40,26.80,27.31,52487900,27.31
2011-10-17,27.11,27.42,26.85,26.98,39433400,26.98
2011-10-14,27.31,27.50,27.02,27.27,50947700,27.27

....

次に、次のことを行います。

#!/usr/bin/env python
from pandas import *

df = read_csv('table.csv')

for i, row in enumerate(df.values):
    date = df.index[i]
    open, high, low, close, adjclose = row
    #now perform analysis on open/close based on date, etc..

それが最も効率的な方法ですか?パンダの速度に焦点を当てていることを考えると、インデックスも取得するように(おそらくメモリ効率を高めるためにジェネレータを介して)値を反復処理するための特別な関数が必要だと思いますか?df.iteritems残念ながら、列ごとに繰り返すだけです。

10 answers

386
Nick Crawford 2012-07-24 07:09.

パンダの最新バージョンには、行を反復処理するための組み込み関数が含まれています。

for index, row in df.iterrows():

    # do some logic here

または、より速く使用したい場合 itertuples()

ただし、行の反復を回避するためにnumpy関数を使用するという、unutbuの提案は、最速のコードを生成します。

156
unutbu 2011-10-21 05:02.

PandasはNumPyアレイに基づいています。NumPy配列を高速化するための鍵は、行ごとまたは項目ごとではなく、配列全体に対して一度に操作を実行することです。

たとえばclose、が1次元配列であり、日ごとのパーセント変化が必要な場合、

pct_change = close[1:]/close[:-1]

これにより、変化率の配列全体が、代わりに1つのステートメントとして計算されます。

pct_change = []
for row in close:
    pct_change.append(...)

したがって、Pythonループをfor i, row in enumerate(...)完全に回避し、行ごとではなく、配列全体(またはデータフレーム)全体に対する操作を使用して計算を実行する方法を検討してください。

100
Richard Wong 2015-12-17 01:39.

前に述べたように、パンダオブジェクトは配列全体を一度に処理するときに最も効率的です。しかし、私のようにパンダのDataFrameをループして何かを実行する必要がある人のために、少なくとも3つの方法を見つけました。3つのうちどれが最も時間がかからないかを確認するために短いテストを行いました。

t = pd.DataFrame({'a': range(0, 10000), 'b': range(10000, 20000)})
B = []
C = []
A = time.time()
for i,r in t.iterrows():
    C.append((r['a'], r['b']))
B.append(time.time()-A)

C = []
A = time.time()
for ir in t.itertuples():
    C.append((ir[1], ir[2]))    
B.append(time.time()-A)

C = []
A = time.time()
for r in zip(t['a'], t['b']):
    C.append((r[0], r[1]))
B.append(time.time()-A)

print B

結果:

[0.5639059543609619, 0.017839908599853516, 0.005645036697387695]

これはおそらく時間消費を測定するための最良の方法ではありませんが、私にとっては迅速です。

ここにいくつかの賛否両論があります私見:

  • .iterrows():インデックスと行アイテムを別々の変数で返しますが、大幅に遅くなります
  • .itertuples():. iterrows()より高速ですが、行アイテムと一緒にインデックスを返します。ir[0]はインデックスです。
  • zip:最速ですが、行のインデックスにアクセスできません

編集2020/11/10

価値があるものとして、ここにいくつかの他の選択肢を備えた更新されたベンチマークがあります(MacBookPro 2,4 GHz Intel Core i98コア32Go 2667 MHz DDR4を使用したパフォーマンス)

import sys
import tqdm
import time
import pandas as pd

B = []
t = pd.DataFrame({'a': range(0, 10000), 'b': range(10000, 20000)})
for _ in tqdm.tqdm(range(10)):
    C = []
    A = time.time()
    for i,r in t.iterrows():
        C.append((r['a'], r['b']))
    B.append({"method": "iterrows", "time": time.time()-A})

    C = []
    A = time.time()
    for ir in t.itertuples():
        C.append((ir[1], ir[2]))
    B.append({"method": "itertuples", "time": time.time()-A})

    C = []
    A = time.time()
    for r in zip(t['a'], t['b']):
        C.append((r[0], r[1]))
    B.append({"method": "zip", "time": time.time()-A})

    C = []
    A = time.time()
    for r in zip(*t.to_dict("list").values()):
        C.append((r[0], r[1]))
    B.append({"method": "zip + to_dict('list')", "time": time.time()-A})

    C = []
    A = time.time()
    for r in t.to_dict("records"):
        C.append((r["a"], r["b"]))
    B.append({"method": "to_dict('records')", "time": time.time()-A})

    A = time.time()
    t.agg(tuple, axis=1).tolist()
    B.append({"method": "agg", "time": time.time()-A})

    A = time.time()
    t.apply(tuple, axis=1).tolist()
    B.append({"method": "apply", "time": time.time()-A})

print(f'Python {sys.version} on {sys.platform}')
print(f"Pandas version {pd.__version__}")
print(
    pd.DataFrame(B).groupby("method").agg(["mean", "std"]).xs("time", axis=1).sort_values("mean")
)

## Output

Python 3.7.9 (default, Oct 13 2020, 10:58:24) 
[Clang 12.0.0 (clang-1200.0.32.2)] on darwin
Pandas version 1.1.4
                           mean       std
method                                   
zip + to_dict('list')  0.002353  0.000168
zip                    0.003381  0.000250
itertuples             0.007659  0.000728
to_dict('records')     0.025838  0.001458
agg                    0.066391  0.007044
apply                  0.067753  0.006997
iterrows               0.647215  0.019600
74
Wes McKinney 2011-10-22 03:04.

iteritemsを転置してから呼び出すことにより、行をループできます。

for date, row in df.T.iteritems():
   # do some logic here

その場合の効率についてはよくわかりません。反復アルゴリズムで可能な限り最高のパフォーマンスを得るには、Cythonでの記述を検討することをお勧めします。そうすれば、次のようなことができます。

def my_algo(ndarray[object] dates, ndarray[float64_t] open,
            ndarray[float64_t] low, ndarray[float64_t] high,
            ndarray[float64_t] close, ndarray[float64_t] volume):
    cdef:
        Py_ssize_t i, n
        float64_t foo
    n = len(dates)

    for i from 0 <= i < n:
        foo = close[i] - open[i] # will be extremely fast

最初に純粋なPythonでアルゴリズムを記述し、それが機能することを確認して、その速度を確認することをお勧めします-十分に高速でない場合は、最小限の作業でこのようにCythonに変換して、手書きのCとほぼ同じ速度のものを取得します/ C ++。

48
Fifi 2018-02-04 23:28.

3つのオプションがあります。

インデックス(最も簡単):

>>> for index in df.index:
...     print ("df[" + str(index) + "]['B']=" + str(df['B'][index]))

iterrows(最も使用):

>>> for index, row in df.iterrows():
...     print ("df[" + str(index) + "]['B']=" + str(row['B']))

itertuples(最速):

>>> for row in df.itertuples():
...     print ("df[" + str(row.Index) + "]['B']=" + str(row.B))

3つのオプションは次のように表示されます。

df[0]['B']=125
df[1]['B']=415
df[2]['B']=23
df[3]['B']=456
df[4]['B']=189
df[5]['B']=456
df[6]['B']=12

出典:neural-networks.io

25
beardc 2012-07-29 18:53.

Nick Crawfordの回答iterrowsに気付いた後でチェックアウトしましたが、(インデックス、シリーズ)タプルが生成されることがわかりました。どちらが最適かはわかりませんが、(index、row_value1 ...)タプルを生成する問題のメソッドを使用することになりました。itertuples

iterkv(列、シリーズ)タプルを反復処理するもあります。

22
Carst 2013-10-17 12:38.

小さな追加と同じように、単一の列に適用する複雑な関数がある場合は、適用を実行することもできます。

http://pandas.pydata.org/pandas-docs/dev/generated/pandas.DataFrame.apply.html

df[b] = df[a].apply(lambda col: do stuff with col here)
14
GoingMyWay 2017-11-07 22:58.

以下のよう@jorisは指摘し、iterrowsはるかに遅いよりitertuplesitertuples約100倍faterよりもiterrows、私は5027505件のレコードをデータフレームの両方のメソッドの速度をテストした結果は用でiterrows、それは1200it / sであり、itertuples120000it / sです。

を使用する場合itertuples、forループ内のすべての要素が名前付きタプルであることに注意してください。したがって、各列の値を取得するには、次のサンプルコードを参照できます。

>>> df = pd.DataFrame({'col1': [1, 2], 'col2': [0.1, 0.2]},
                      index=['a', 'b'])
>>> df
   col1  col2
a     1   0.1
b     2   0.2
>>> for row in df.itertuples():
...     print(row.col1, row.col2)
...
1, 0.1
2, 0.2
10
Vlad 2018-03-23 15:51.

確かに、データフレームを反復処理する最も速い方法は、df.values(あなたが行うように)または各列に個別にアクセスすることによって、基礎となるnumpyndarrayにアクセスすることですdf.column_name.values。インデックスにもアクセスしたいのでdf.index.values、そのために使用できます。

index = df.index.values
column_of_interest1 = df.column_name1.values
...
column_of_interestk = df.column_namek.values

for i in range(df.shape[0]):
   index_value = index[i]
   ...
   column_value_k = column_of_interest_k[i]

pythonicではありませんか?承知しました。しかし、速い。

ループからさらにジュースを絞りたい場合は、cythonを調べてください。Cythonを使用すると、大幅なスピードアップが可能になります(10x-100xと考えてください)。最大のパフォーマンスを得るには、cythonのメモリビューを確認してください。

5
JoeCondron 2014-11-15 02:30.

別の提案は、行のサブセットが特性を共有している場合に、groupbyをベクトル化された計算と組み合わせることです。

Related questions

MORE COOL STUFF

「水曜日」シーズン1の中心には大きなミステリーがあります

「水曜日」シーズン1の中心には大きなミステリーがあります

Netflixの「水曜日」は、典型的な10代のドラマ以上のものであり、実際、シーズン1にはその中心に大きなミステリーがあります.

ボディーランゲージの専門家は、州訪問中にカミラ・パーカー・ボウルズが輝くことを可能にした微妙なケイト・ミドルトンの動きを指摘しています

ボディーランゲージの専門家は、州訪問中にカミラ・パーカー・ボウルズが輝くことを可能にした微妙なケイト・ミドルトンの動きを指摘しています

ケイト・ミドルトンは、州の夕食会と州の訪問中にカミラ・パーカー・ボウルズからスポットライトを奪いたくなかった、と専門家は言う.

一部のファンがハリー・スタイルズとオリビア・ワイルドの「非常に友好的な」休憩が永続的であることを望んでいる理由

一部のファンがハリー・スタイルズとオリビア・ワイルドの「非常に友好的な」休憩が永続的であることを望んでいる理由

一部のファンが、オリビア・ワイルドが彼女とハリー・スタイルズとの間の「難しい」が「非常に友好的」な分割を恒久的にすることを望んでいる理由を見つけてください.

エリザベス女王の死後、ケイト・ミドルトンはまだ「非常に困難な時期」を過ごしている、と王室の専門家が明らかにする 

エリザベス女王の死後、ケイト・ミドルトンはまだ「非常に困難な時期」を過ごしている、と王室の専門家が明らかにする&nbsp;

エリザベス女王の死後、ケイト・ミドルトンが舞台裏で「非常に困難な時期」を過ごしていたと伝えられている理由を調べてください.

セントヘレナのジェイコブのはしごを登るのは、気弱な人向けではありません

セントヘレナのジェイコブのはしごを登るのは、気弱な人向けではありません

セント ヘレナ島のジェイコブズ ラダーは 699 段の真っ直ぐ上る階段で、頂上に到達すると証明書が発行されるほどの難易度です。

The Secrets of Airline Travel Quiz

The Secrets of Airline Travel Quiz

Air travel is far more than getting from point A to point B safely. How much do you know about the million little details that go into flying on airplanes?

Where in the World Are You? Take our GeoGuesser Quiz

Where in the World Are You? Take our GeoGuesser Quiz

The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!

バイオニック読書はあなたをより速く読むことができますか?

バイオニック読書はあなたをより速く読むことができますか?

BionicReadingアプリの人気が爆発的に高まっています。しかし、それは本当にあなたを速読術にすることができますか?

HMSプリンスオブウェールズの橋はスターウォーズからまっすぐです

HMSプリンスオブウェールズの橋はスターウォーズからまっすぐです

BAE Systems Maritimeは昨日、英国海軍の2番目のクイーンエリザベスクラスの空母であるHMSプリンスオブウェールズのブリッジモジュールを展開しました。公海を航海するよりも、アウターリムの惑星を周回してタイファイターを発射する必要があるようです。70,000の排水量のトン運搬船は、2020年に就役し、姉のエリザベス女王と同様に、約40機の航空機を運ぶ予定です。

ルイビルはサヨナラゲームでウェイクフォレストを倒すために家を盗んだ

ルイビルはサヨナラゲームでウェイクフォレストを倒すために家を盗んだ

ルイビルは、通常の大学野球の強みであるピッチング、ディフェンス、スマートベースランニングを通じて、全国ランキングのトップ5と19-2の会議記録への道を歩みました。昨夜、彼らは野球の最もエキサイティングなプレーの1つである盗塁を使用して、ウェイクフォレストのスイープを完了しました。

おいしいツイストのためにコーンブレッドであなたの次のサンドイッチを作りましょう

おいしいツイストのためにコーンブレッドであなたの次のサンドイッチを作りましょう

粗いパン粉とふわふわの食感のコーンブレッドは、唐辛子を吸い上げるのに理想的な乗り物です。しかし、それだけではありません。

別の驚くべきマーベルヒーローがキャプテンアメリカに参加します:シビルウォー!

別の驚くべきマーベルヒーローがキャプテンアメリカに参加します:シビルウォー!

ニール・ブロムカンプが、チャッピーが第10地区をどのように遅らせたのかについて話します。フォースの覚醒の噂は、次の予告編に何を期待するかについてのいじめを提供します。

ケイト・ミドルトンとウィリアム王子は、彼らが子供たちと行っているスパイをテーマにした活動を共有しています

ケイト・ミドルトンとウィリアム王子は、彼らが子供たちと行っているスパイをテーマにした活動を共有しています

ケイト・ミドルトンとウィリアム王子は、子供向けのパズルの本の序文を書き、ジョージ王子、シャーロット王女、ルイ王子と一緒にテキストを読むと述べた.

事故で押しつぶされたスイカは、動物を喜ばせ水分補給するために野生生物保護団体に寄付されました

事故で押しつぶされたスイカは、動物を喜ばせ水分補給するために野生生物保護団体に寄付されました

Yak's Produce は、数十個のつぶれたメロンを野生動物のリハビリ専門家であるレスリー グリーンと彼女のルイジアナ州の救助施設で暮らす 42 匹の動物に寄付しました。

デミ・ロヴァートは、新しいミュージシャンのボーイフレンドと「幸せで健康的な関係」にあります: ソース

デミ・ロヴァートは、新しいミュージシャンのボーイフレンドと「幸せで健康的な関係」にあります: ソース

8 枚目のスタジオ アルバムのリリースに向けて準備を進めているデミ ロヴァートは、「スーパー グレート ガイ」と付き合っている、と情報筋は PEOPLE に確認しています。

Plathville の Kim と Olivia Plath が数年ぶりに言葉を交わすことへようこそ

Plathville の Kim と Olivia Plath が数年ぶりに言葉を交わすことへようこそ

イーサン プラスの誕生日のお祝いは、TLC のウェルカム トゥ プラスビルのシーズン 4 のフィナーレで、戦争中の母親のキム プラスと妻のオリビア プラスを結びつけました。

仕事の生産性を高める 8 つのシンプルなホーム オフィスのセットアップのアイデア

仕事の生産性を高める 8 つのシンプルなホーム オフィスのセットアップのアイデア

ホームオフィスのセットアップ術を極めよう!AppExert の開発者は、家族全員が一緒にいる場合でも、在宅勤務の技術を習得しています。祖父や曽祖父が共同家族で暮らしていた頃の記憶がよみがえりました。

2022 年、私たちのデジタル ライフはどこで終わり、「リアル ライフ」はどこから始まるのでしょうか?

20 年前のタイムトラベラーでさえ、日常生活におけるデジタルおよびインターネットベースのサービスの重要性に驚くことでしょう。MySpace、eBay、Napster などのプラットフォームは、高速化に焦点を合わせた世界がどのようなものになるかを示してくれました。

ニューロマーケティングの秘密科学

ニューロマーケティングの秘密科学

マーケティング担当者が人間の欲望を操作するために使用する、最先端の (気味が悪いと言う人もいます) メソッドを探ります。カートをいっぱいにして 3 桁の領収書を持って店を出る前に、ほんの数点の商品を買いに行ったことはありませんか? あなたは一人じゃない。

地理情報システムの日: GIS 開発者として学ぶべき最高の技術スタック

地理情報システムの日: GIS 開発者として学ぶべき最高の技術スタック

私たちが住んでいる世界を確実に理解するには、データが必要です。ただし、空間参照がない場合、このデータは地理的コンテキストがないと役に立たなくなる可能性があります。

Language