numpy, erhöhe das Maximum der Teilmengen

8

Ich habe ein Array von Werten, sagte v , (z. B. v=[1,2,3,4,5,6,7,8,9,10] ) und ein Array von Indizes, sagen wir g (z. B. g=[0,0,0,0,1,1,1,1,2,2] ).

Ich weiß zum Beispiel, wie man das erste Element jeder Gruppe auf sehr numptonische Weise macht:

%Vor%

gibt zurück:

%Vor%

Gibt es irgendeine numpy thonische Weise (um explizite Schleifen zu vermeiden), um das Maximum jeder Teilmenge zu erhalten?

Tests:

Da ich zwei gute Antworten erhielt, eine mit der Python map und eine mit einer numpy Routine, und ich suchte die leistungsfähigste, hier einige Zeittests:

%Vor%

Als Ergebnis bekomme ich:

%Vor%

Interessanterweise ist der größte Teil der Verlangsamung der Methode map auf den Aufruf list() zurückzuführen. Wenn ich nicht versuche, mein map Ergebnis in ein list umzuwandeln (aber ich muss, weil python3.x einen Iterator zurückgibt: Ссылка )

    
Antonio Ragagnin 10.12.2015, 17:46
quelle

3 Antworten

4

Sie können verwenden np.maximum.reduceat :

%Vor%

Weitere Informationen über die Funktionsweise des ufunc reduceat -Methode können hier zu finden .

Bemerkung über die Leistung

np.maximum.reduceat ist sehr schnell. Die Erzeugung der Indizes idx ist das, was hier den größten Teil der Zeit in Anspruch nimmt.

Während _, idx = np.unique(g, return_index=True) eine elegante Art ist, die Indizes zu erhalten, ist es nicht besonders schnell.

Der Grund ist, dass np.unique das Array zuerst sortieren muss, was O (n log n) in der Komplexität ist. Bei großen Arrays ist dies viel teurer als die Verwendung mehrerer O (n) -Operationen zum Generieren von idx .

Daher ist es bei großen Arrays viel schneller, stattdessen Folgendes zu verwenden:

%Vor%     
Alex Riley 10.12.2015, 18:05
quelle
2

Hier ist ein verschachtelter vektorisierter Ansatz mit masking und broadcasting , die jede Gruppe in Reihen eines normalen 2D-Bildes einreihen Array und findet dann Maximum entlang jeder Zeile -

%Vor%

Beispiellauf -

%Vor%     
Divakar 10.12.2015 18:03
quelle
2

Sie können Ihre Maske wie folgt erstellen und map function verwenden:

%Vor%

Wenn Sie keinen Generator mit map erhalten möchten, können Sie ein Listenverständnis verwenden, um das gleiche Ergebnis in der Liste zu erzielen. Beachten Sie, dass die Iteration des Listenverständnisses mit der C-Geschwindigkeit im Interpreter ausgeführt wurde -in Funktionen.

%Vor%

Aber ich denke, die numpythonische Lösung ist immer noch besser zu benutzen.

    
Kasramvd 10.12.2015 17:58
quelle