mit Python, wählen Sie wiederholte Elemente länger als N

8

Angenommen, ich habe einen Datenrahmen wie folgt:

%Vor%

Ich versuche, die Zahlen zu filtern, die viermal oder öfter wiederholt werden, und die Ausgabe wird lauten:

%Vor%

Momentan benutze ich itemfreq , um diese Informationen zu extrahieren, dies führt zu einer Reihe von Arrays, bei denen es dann kompliziert ist, eine Bedingung zu machen und nur diese Zahlen zu filtern. Ich denke, dass es einen anderen einfachsten Weg dafür geben muss. Einige Ideen? Danke!

    
Jonathan Pacheco 01.09.2017, 20:26
quelle

5 Antworten

5

Approach # 1: Einer der NumPy-Wege wäre -

%Vor%

Approach # 2: NumPy + Pandas mischen One-Liner für positive Zahlen -

%Vor%

Approach # 3: Unter Verwendung der Tatsache, dass der Datenrahmen in der relevanten Spalte sortiert ist, ist hier ein tiefer NumPy-Ansatz -

%Vor%

Benchmarking

@piRSquared hat ein umfangreiches Benchmarking für alle bisher veröffentlichten Ansätze abgedeckt und es scheint, als ob pir1_5 und div3 scheint dort die top-2 zu sein. Aber das Timing scheint vergleichbar zu sein und es hat mich zu einem genaueren Blick ermutigt. In diesem Benchmarking hatten wir timeit(stmt, setp, number=10) , das eine konstante Anzahl von Iterationen zum Ausführen von timeit verwendet, was nicht die zuverlässigste Methode für das Timing ist, speziell für kleine Datensätze. Auch die Datensätze schienen dort klein zu sein, da die Zeiten für den größten Datensatz in micro-sec lagen. Um diese beiden Probleme zu mildern, schlage ich vor, IPythons %timeit zu verwenden, das automatisch die optimale Anzahl von Iterationen für die Laufzeit von timeit berechnet, d. H. Eine größere Anzahl von Iterationen für kleinere Datensätze als für größere. Dies sollte zuverlässiger sein. Außerdem schlage ich vor, größere Datensätze hinzuzufügen, damit die Zeiten in milli-sec und sec gehen. Mit diesen paar Änderungen sah das neue Benchmarking-Setup ungefähr so ​​aus (denken Sie daran, dass Sie kopieren und in die IPython-Konsole einfügen, um dies auszuführen) -

%Vor%

Der Vollständigkeit halber waren die Ansätze -

%Vor%

Das Timing-Setup wurde auf der IPython-Konsole ausgeführt (da wir magische Funktionen verwenden). Die Ergebnisse sahen so aus -

%Vor%

Daher sind Beschleunigungswerte mit div3 über pir1_5 :

%Vor%     
Divakar 01.09.2017, 20:34
quelle
7

groupby.filter ist wahrscheinlich der einfachste Weg:

%Vor%     
ayhan 01.09.2017 20:28
quelle
5

numpy
In dieser Lösung verfolge ich, wo die Werte nicht gleich dem nachfolgenden Wert sind. Wenn man dann np.diff dieser Positionen nimmt, erhält man die Länge jeder Subsequenz.
Ich kann dann testen, ob die Länge > 3 ist und np.repeat mit der gleichen Liste von Längen verwenden, um das boolesche Array zu erhalten, das für das Slicing benötigt wird.

%Vor%

numba
Verwenden Sie den numba s JIT-Compiler, um einen linearen Algorithmus auszuführen

%Vor%

Timing

%Vor%

CODE

Funktionen

%Vor%

Testen

%Vor%     
piRSquared 01.09.2017 20:54
quelle
4

Nur value_counts

%Vor%

Timing:

%Vor%

@ Divakars Antwort ist die ~ schnellste ~, im Moment ist es Pirs Antwort.

EDIT: Tut mir leid, Jungs, weil ich zu Hause bin, ich wiederhole das Timing wieder

%Vor%     
Wen 01.09.2017 20:39
quelle
2

Mit pandas.Dataframe.tranform() Funktion:

%Vor%

Die Ausgabe:

%Vor%     
RomanPerekhrest 01.09.2017 20:35
quelle

Tags und Links