Abkürzungsauswertung von numpys Array-Vergleich

9

Wenn ich in numpy zwei Arrays vergleichen möchte, zum Beispiel wenn ich testen möchte, ob alle Elemente in A kleiner als Werte in B sind, verwende ich if (A < B).all(): . In der Praxis erfordert dies jedoch die Zuweisung und Auswertung des vollständigen Arrays C = A < B und dann den Aufruf von C.all() . Das ist ein bisschen Verschwendung. Gibt es eine Möglichkeit, den Vergleich zu "verkürzen", d. H.% Co_de% Element für Element (ohne Zuweisung und Berechnung von temporärem A < B ) direkt auszuwerten und C zu stoppen und zurückzugeben, wenn der erste ungültige Elementvergleich gefunden wird?

    
V.K. 18.01.2016, 10:19
quelle

2 Antworten

0

Plain Python and und or verwenden die Shortcut-Auswertung, numpy jedoch nicht.

%Vor%

verwendet numpy building blocks, den Broadcasting, den elementweisen Vergleich mit < und die all Reduktion. Das < arbeitet nur mit anderen binären Operationen, plus, mal und, oder, gt, le usw. Und all ist wie andere Reduktionsverfahren, any , max , sum , mean , und kann auf dem gesamten Array oder nach Zeilen oder Spalten arbeiten.

Es ist möglich, eine Funktion zu schreiben, die all und < in einer Iteration kombiniert, aber es wäre schwierig, die soeben beschriebene Allgemeinheit zu erhalten.

Wenn Sie jedoch eine iterative Lösung mit einer Verknüpfungsaktion implementieren und dies schnell tun müssen, würde ich vorschlagen, die Idee mit nditer zu entwickeln und sie dann mit cython zu kompilieren.

Ссылка ist ein gutes Tutorial zur Verwendung von nditer , das Sie braucht durch Verwendung in cython . nditer kümmert sich um Broadcasting und Iteration, sodass Sie sich auf den Vergleich und die Verknüpfung konzentrieren können.

Hier ist eine Skizze eines Iterators, der in cython :

umgewandelt werden kann %Vor%

mit einem Beispiellauf:

%Vor%

Beginne mit einer Standard False und einer anderen break Bedingung und du erhältst eine Abkürzung any . Die Verallgemeinerung des Tests zur Behandlung von < , <= usw. ist mehr Arbeit.

Erhalte so etwas in Python und versuche es dann in Cython. Wenn Sie Probleme mit diesem Schritt haben, kommen Sie mit einer neuen Frage zurück. SO hat eine gute Basis für Cython-Benutzer.

    
hpaulj 18.01.2016, 22:33
quelle
1

Wie groß sind Ihre Arrays? Ich könnte mir vorstellen, dass sie sehr groß sind, z.B. A.shape = (1000000) oder größer, bevor die Leistung zum Problem wird. Würden Sie in Erwägung ziehen, Ansichten zu verwenden?

Anstatt (A < B).all() oder (A < B).any() zu vergleichen, können Sie versuchen, eine Ansicht zu definieren, z. B. (A[:10] < B[:10]).all() . Hier ist eine einfache Schleife, die funktionieren könnte:

%Vor%

Anstelle von 10 können Sie 100 oder 10**3 Segmentgröße verwenden, die Sie wünschen. Offensichtlich, wenn Ihre Segmentgröße 1 ist, sagen Sie:

%Vor%

Manchmal kann der Vergleich des gesamten Arrays speicherintensiv werden. Wenn A und B eine Länge von 10000 haben und ich jedes Paar Elemente vergleichen muss, wird mir der Platz ausgehen.

    
john mangual 18.01.2016 20:24
quelle

Tags und Links