Ich versuche eine Funktion zu implementieren, die die ersten aufeinanderfolgenden Vorkommen in einem Pandas Series
identifiziert, das bereits mit der gewünschten Bedingung maskiert wurde: (z. B.)
[True, True, True, False, True, False, True, True, True, True]
Ich möchte, dass die obige Eingabe das Ergebnis von 3
ergibt, d. h. es gibt 3 True
Vorkommen in einer Zeile vom Beginn der Serie.
Ich bin mir bewusst, dass eine große for
-Schleife die Arbeit machen würde, aber gibt es irgendeine vektorisierte / Pandas-zentrierte Art, sie zu umgehen?
Vielen Dank.
Finde die Anzahl der ersten aufeinanderfolgenden True
s
Betrachte a
Antwort 1
numpy
: Benutze np.logical_and.accumulate
für die Negation von a
und nimm die Negation, um eine Maske zu erstellen, die die erste Reihe von False
s eliminiert wenn sie existieren sollten. Dann fügen Sie am Ende ein False
hinzu, um sicherzustellen, dass wir ein nicht True
min haben. Verwenden Sie schließlich np.argmin
, um den ersten Mindestwert zu finden. Wenn es eine Position 3
gefunden hat, zeigt das 3
True
Werte davor an.
Antwort 2
numba.njit
Ich möchte numba
verwenden, damit ich eine Schleife machen kann und sicherstellen kann, dass ich einen Kurzschluss erhalte, wenn wir wollen / müssen. Dies ist ein Problem, das sicher früh im Array beantwortet wird. Es ist nicht notwendig, die Dinge entlang des gesamten Arrays ohne Grund zu bewerten.
Antwort 3
numpy
intelligentere Verwendung von argmin
und argmax
. Ich umschließe a
mit False
und dann argmax
, um die erste True
zu finden. Von diesem Punkt an, benutze argmin
, um danach die erste False
zu finden.
Hinweis: @Divakar hat eine Verbesserung dieser Antwort vorgenommen, die die Verwendung von np.concatenate
eliminiert und stattdessen if/then/else
verwendet. Das hat diese schon sehr schnelle Lösung um einen Faktor von 3
gekappt!
Wie schnell sind diese Antworten?
Siehe @ Divakars Antwort für den Quellcode anderer zeitgesteuerter Funktionen
Mit NumPy-Funktionen wäre eine Lösung -
%Vor%Beispiellauf -
%Vor% Für die Leistung müssen wir np.concatenate
anstelle von np.r_
verwenden und dann die letzte Differenzierung durchschneiden -
Inspiriert von @ piRSquared's argmax
und argmin
trickery , hier ist noch eins mit einem Haufen IF-ELSE
's -