Pandas: Was ist der effizienteste Weg, um den DataFrame von Pandas zeilenweise zu durchlaufen?

Erstellt am 12. Juni 2015  ·  6Kommentare  ·  Quelle: pandas-dev/pandas

Ich habe die Funktion df.iterrows() ausprobiert, aber ihre Leistung ist schrecklich. Was nicht verwunderlich ist, da iterrows() ein Series mit vollständigen Schema- und Metadaten zurückgibt, nicht nur die Werte (die alles sind, was ich brauche).

Die zweite Methode, die ich ausprobiert habe, ist for row in df.values , was erheblich schneller ist. Ich habe jedoch kürzlich festgestellt, dass df.values nicht der interne Datenspeicher des DataFrame ist, da df.values alle dtypes in ein gemeinsames dtype konvertiert. Zum Beispiel hat eine meiner Spalten den D-Typ int64 aber der D-Typ von df.values ist alles float64 . Ich vermute also, dass df.values tatsächlich eine weitere Kopie der internen Daten erstellt.

Eine weitere Anforderung besteht darin, dass die Zeileniteration eine Liste von Werten zurückgeben muss, die die ursprünglichen dtype der Daten beibehalten.

Usage Question

Hilfreichster Kommentar

Ich denke, df.itertuples() ist das, wonach Sie suchen - es ist viel schneller als iterrows:

In [10]: x = pd.DataFrame({'x': range(10000)})

In [11]: %timeit list(x.iterrows())
1 loops, best of 3: 383 ms per loop

In [12]: %timeit list(x.itertuples())
1000 loops, best of 3: 1.39 ms per loop

Alle 6 Kommentare

In Python wird das Iterieren über die Zeilen (viel) langsamer sein als das Ausführen von vektorisierten Operationen.

Die Typen werden in Ihrer zweiten Methode konvertiert, da so numpy Arrays (was df.values ist) funktionieren. DataFrames sind spaltenbasiert, sodass Sie einen einzelnen DataFrame mit mehreren dtypes haben können. Sobald Sie zeilenweise iterieren, muss alles auf einen allgemeineren Typ übertragen werden, der alles enthält. In Ihrem Fall gehen die Ints zu float64 .

Wenn Sie Ihr Problem anhand eines minimalen Arbeitsbeispiels beschreiben, können wir Ihnen möglicherweise bei der Vektorisierung helfen. Sie können auch Glück auf StackOverflow mit dem Pandas-Tag haben.

Grundsätzlich möchte ich Folgendes tun:

row_handler = RowHandler(sample_df)  # learn how to handle row from sample data
transformed_data = []
for row in df.values:
    transformed_data.append(row_handler.handle(row))
return transformed_data

Ich besitze die Klasse RowHandler und kann daher nur zeilenweise arbeiten.

Ein weiteres ähnliches Beispiel ist das maschinelle Lernen, bei dem Sie möglicherweise ein Modell haben, das die API nur auf Zeilenebene vorhersagt.

Immer noch etwas zu vage, um hilfreich zu sein. Aber wenn RowHandler wirklich außerhalb Ihrer Kontrolle liegt, haben Sie kein Glück. FWIW Alle APIs von scikit-learn arbeiten mit Arrays (also mehreren Zeilen).

Ich sehe nicht, wie es klarer sein kann. Ja, RowHandler liegt außerhalb meiner Kontrolle. Was meinst du mit Pech? Meine Frage ist, wie man am effizientesten über Zeilen iteriert und dabei die dtype jedes Elements intakt hält. Schlagen Sie df.iterrows() oder etwas anderes vor?

sklearn ist eine Ausnahme, nicht die Norm, die nativ auf PDs DataFrame . Nicht viele Bibliotheken für maschinelles Lernen verfügen über APIs, die mit DataFrame .

Ich denke, df.itertuples() ist das, wonach Sie suchen - es ist viel schneller als iterrows:

In [10]: x = pd.DataFrame({'x': range(10000)})

In [11]: %timeit list(x.iterrows())
1 loops, best of 3: 383 ms per loop

In [12]: %timeit list(x.itertuples())
1000 loops, best of 3: 1.39 ms per loop

Danke @shoyer! Das ist was ich brauche.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen