395 Stimmen

Was ist der effizienteste Weg, um Schleife durch dataframes mit Pandas?

Ich möchte meine eigenen komplexen Operationen auf Finanzdaten in Datenrahmen in sequenzieller Weise durchführen.

Ich verwende zum Beispiel die folgende CSV-Datei von MSFT Yahoo Finanzen :

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

....

Ich gehe dann wie folgt vor:

#!/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..

Ist das der effizienteste Weg? Angesichts der Fokus auf Geschwindigkeit in Pandas, würde ich davon ausgehen, dass es einige spezielle Funktion, um durch die Werte in einer Weise, die man auch den Index abruft (möglicherweise durch einen Generator, um speichereffizient zu sein) zu iterieren sein muss? df.iteritems iteriert leider nur spaltenweise.

26voto

beardc Punkte 18685

Ich überprüfte iterrows nachdem ich festgestellt habe Nick Crawfords Antwort, stellte aber fest, dass sie (Index, Serie) Tupel ergibt. Ich bin mir nicht sicher, was für Sie am besten funktionieren würde, aber ich habe am Ende die itertuples Methode für mein Problem, die (index, row_value1...) Tupel liefert.

Außerdem gibt es iterkv die die Tupel (Spalte, Reihe) durchläuft.

21voto

Carst Punkte 1594

Als kleine Ergänzung können Sie auch eine Anwendung durchführen, wenn Sie eine komplexe Funktion auf eine einzelne Spalte anwenden:

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

df[b] = df[a].apply(lambda col: do stuff with col here)

15voto

GoingMyWay Punkte 15426

Als @joris hervorgehoben, iterrows ist viel langsamer als itertuples y itertuples ist etwa 100 Mal schneller als iterrows und ich habe die Geschwindigkeit beider Methoden in einem DataFrame mit 5 Millionen Datensätzen getestet, das Ergebnis ist für iterrows ist 1200it/s, und itertuples beträgt 120000it/s.

Wenn Sie itertuples Beachten Sie, dass jedes Element in der for-Schleife ein Nameduple ist. Um den Wert in jeder Spalte zu erhalten, können Sie den folgenden Beispielcode verwenden

>>> 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

12voto

Vladimirs Punkte 860

Der schnellste Weg, über einen Datenrahmen zu iterieren, ist sicherlich der Zugriff auf das zugrunde liegende Numpy-Ndarray entweder über df.values (wie Sie es tun) oder durch separaten Zugriff auf jede Spalte df.column_name.values . Da Sie auch Zugriff auf den Index haben wollen, können Sie df.index.values dafür.

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]

Nicht pythonisch? Sicher. Aber schnell.

Wenn Sie mehr aus der Schleife herausholen wollen, sollten Sie sich mit folgenden Themen befassen cython . Mit Cython können Sie enorme Geschwindigkeitssteigerungen erzielen (z.B. 10x-100x). Für maximale Leistung prüfen Sie Speicheransichten für Cython .

5voto

JoeCondron Punkte 7806

Ein weiterer Vorschlag wäre, groupby mit vektorisierten Berechnungen zu kombinieren, wenn Teilmengen der Zeilen gemeinsame Merkmale aufweisen, die dies ermöglichen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X