Warum Verkettung von DataFrames, exponentiell langsamer?
Ich habe eine Funktion, die Prozesse, die ein DataFrame, weitgehend zum verarbeiten von Daten in buckets erstellen Sie eine binäre matrix von Funktionen, die in einer bestimmten Spalte mit pd.get_dummies(df[col])
.
Zu vermeiden, Verarbeitung all meine Daten mit dieser Funktion auf einmal (das geht out of memory und Ursachen iPython zum Absturz), ich habe gebrochen die große DataFrame in Stücke Verwendung:
chunks = (len(df) / 10000) + 1
df_list = np.array_split(df, chunks)
pd.get_dummies(df)
automatisch neue Spalten erstellen, basierend auf dem Inhalt der df[col]
- und diese unterscheiden sich mit hoher Wahrscheinlichkeit für jeden df
im df_list
.
Nach der Verarbeitung, ich bin die Verkettung des DataFrames wieder zusammen mit:
for i, df_chunk in enumerate(df_list):
print "chunk", i
[x, y] = preprocess_data(df_chunk)
super_x = pd.concat([super_x, x], axis=0)
super_y = pd.concat([super_y, y], axis=0)
print datetime.datetime.utcnow()
Die Bearbeitungszeit der erste chunk ist durchaus akzeptabel, aber es wächst pro Stück! Dies ist nicht zu tun mit der preprocess_data(df_chunk)
als dort ist kein Grund, es zu erhöhen. Ist dieser Anstieg in der Zeit, die als Ergebnis des Anrufs zu pd.concat()
?
Bitte siehe log unten:
chunks 6
chunk 0
2016-04-08 00:22:17.728849
chunk 1
2016-04-08 00:22:42.387693
chunk 2
2016-04-08 00:23:43.124381
chunk 3
2016-04-08 00:25:30.249369
chunk 4
2016-04-08 00:28:11.922305
chunk 5
2016-04-08 00:32:00.357365
Gibt es einen workaround, um diese Fahrt? Ich habe 2900 Stücke zu verarbeiten, so jede Hilfe wird sehr geschätzt!
Offen für andere Vorschläge in Python!
Du musst angemeldet sein, um einen Kommentar abzugeben.
Nie rufen
DataFrame.append
oderpd.concat
innerhalb einer for-Schleife. Es führt zu quadratischen kopieren.pd.concat
gibt ein neues DataFrame. Der Raum zugeteilt, für die neueDataFrame, und die Daten vom alten DataFrames kopiert werden in die neue
DataFrame. Betrachten Sie die Menge kopieren, die nach dieser Linie innerhalb der
for-loop
(vorausgesetzt, jederx
hat Größe 1):1 + 2 + 3 + ... + N = N(N+1)/2
. So gibt esO(N**2)
Kopien erforderlichvervollständigen Sie die Schleife.
Betrachten wir nun
Anhängen an eine Liste ein
- O(1)
operation und erfordert nicht kopieren. Jetztes ist ein einziger Aufruf
pd.concat
nachdem die Schleife fertig ist. Dieser Aufrufpd.concat
erfordert N Kopien gemacht werden, dasuper_x
enthältN
DataFrames der Größe 1. Also, wenn so konstruiert,
super_x
erfordertO(N)
Kopien.
Jedes mal, wenn Sie verketten, das Sie wieder eine Kopie der Daten.
Sie wollen, machen Sie eine Liste Ihrer Stücke, und dann verketten alles, wie der Letzte Schritt.