Ich suche nach Lösungen, um eine Funktion zu beschleunigen, die ich geschrieben habe, um einen Pandas-Datenrahmen zu durchlaufen und Spaltenwerte zwischen der aktuellen Zeile und der vorherigen Zeile zu vergleichen .Schnellste Möglichkeit zum Vergleichen von Zeilen und vorherigen Zeilen im Pandas-Datenframe mit Millionen von Zeilen
Als Beispiel ist dies eine vereinfachte Version von meinem Problem:
User Time Col1 newcol1 newcol2 newcol3 newcol4
0 1 6 [cat, dog, goat] 0 0 0 0
1 1 6 [cat, sheep] 0 0 0 0
2 1 12 [sheep, goat] 0 0 0 0
3 2 3 [cat, lion] 0 0 0 0
4 2 5 [fish, goat, lemur] 0 0 0 0
5 3 9 [cat, dog] 0 0 0 0
6 4 4 [dog, goat] 0 0 0 0
7 4 11 [cat] 0 0 0 0
Im Moment habe ich eine Funktion, die durch Schleifen und berechnet Werte für ‚newcol1
‘ und ‚newcol2
‘ basierend darauf, ob die ' User
'hat sich seit der vorherigen Zeile geändert und auch, ob der Unterschied in den Werten' Time
'größer als 1 ist. Es wird auch der erste Wert in den Arrays unter' Col1
'und' Col2
'und Aktualisierungen' newcol3
'und' newcol4
', wenn sich diese Werte seit der letzten Zeile geändert haben.
Hier ist der Pseudo-Code für das, was ich zur Zeit mache (da ich das Problem vereinfacht habe ich nicht getestet, aber es ist ziemlich ähnlich zu dem, was ich in ipython Notebook tatsächlich tun):
def myJFunc(df):
... #initialize jnum counter
... jnum = 0;
... #loop through each row of dataframe (not including the first/zeroeth)
... for i in range(1,len(df)):
... #has user changed?
... if df.User.loc[i] == df.User.loc[i-1]:
... #has time increased by more than 1 (hour)?
... if abs(df.Time.loc[i]-df.Time.loc[i-1])>1:
... #update new columns
... df['newcol2'].loc[i-1] = 1;
... df['newcol1'].loc[i] = 1;
... #increase jnum
... jnum += 1;
... #has content changed?
... if df.Col1.loc[i][0] != df.Col1.loc[i-1][0]:
... #record this change
... df['newcol4'].loc[i-1] = [df.Col1.loc[i-1][0], df.Col2.loc[i][0]];
... #different user?
... elif df.User.loc[i] != df.User.loc[i-1]:
... #update new columns
... df['newcol1'].loc[i] = 1;
... df['newcol2'].loc[i-1] = 1;
... #store jnum elsewhere (code not included here) and reset jnum
... jnum = 1;
Ich muss jetzt diese Funktion auf mehrere Millionen Zeilen anwenden und es ist unglaublich langsam, so dass ich versuche, herauszufinden, der beste Weg, um es zu beschleunigen. Ich habe gehört, dass Cython die Geschwindigkeit von Funktionen erhöhen kann, aber ich habe keine Erfahrung damit (und ich bin neu sowohl Pandas und Pandas). Ist es möglich, zwei Zeilen eines Datenframes als Argumente an die Funktion zu übergeben und dann Cython zu verwenden, um sie zu beschleunigen, oder müssten neue Spalten mit "diff
" -Werten erstellt werden, sodass die Funktion nur liest und in eine schreibt Zeile des Datenrahmens gleichzeitig, um von der Verwendung von Cython zu profitieren? Alle anderen Geschwindigkeitstricks würden sehr geschätzt werden!
(Was .loc verwenden, verglich ich .loc, .iloc und .ix und dieses war geringfügig schneller, so das ist der einzige Grund, warum ich das zur Zeit bin mit)
(Auch meine User
Spalte in Realität ist Unicode nicht int, was für schnelle Vergleiche problematisch sein könnte)
Mit einer Million Zeilen, warum nicht eine dedizierte Datenbank verwenden, mit der Python einfach Verbindungen wie MySQL oder SQLlite herstellen kann? Relationale Datenbanken können komplexe SQL-Abfragen mit if/then-Logik für den Zeilen-zu-Zeilen-Vergleich ausführen, die durch Indizes verbunden sind. Sie sind entworfen, um Millionen von Zeilen zu skalieren. Selbst ein Trigger kann so eingerichtet werden, dass bei jeder Benutzeränderung bestimmte Spalten aktualisiert werden können. – Parfait