2014-08-29 14 views
6

Ich habe eine große (ca. 14.000 x 14.000) quadratische Matrix als Numpy ndarray dargestellt. Ich möchte eine große Anzahl von Zeilen und Spalten extrahieren - die Indizes, von denen ich im Voraus weiß, obwohl es tatsächlich alle Zeilen und Spalten sind, die nicht alle Null sind -, um eine neue quadratische Matrix zu erhalten (ca. 10.000 x 10.000).Was ist der schnellste Weg, um bestimmte Zeilen und Spalten aus einem Numpy NDarray zu extrahieren?

Der schnellste Weg, die ich gefunden habe, dies zu tun ist:

> timeit A[np.ix_(indices, indices)] 
1 loops, best of 3: 6.19 s per loop 

Dies ist jedoch viel langsamer als die Zeit, die Matrix-Multiplikation zu tun:

> timeit np.multiply(A, A) 
1 loops, best of 3: 982 ms per loop 

Dies scheint seltsam, da Sowohl die Zeilen-/Spaltenextraktion als auch die Matrixmultiplikation müssen ein neues Array zuweisen (das für das Ergebnis der Matrixmultiplikation noch größer ist als für die Extraktion), aber die Matrixmultiplikation muss auch zusätzliche Berechnungen durchführen.

Also die Frage: Gibt es einen effizienteren Weg, um die Extraktion, insbesondere mindestens so schnell wie Matrixmultiplikation durchzuführen?

+0

Ich vermute, der Grund, warum Matrixmultiplikation schnell ist, liegt darin, dass es alle Elemente des Arrays auf eine streng reguläre Weise verwendet und dafür optimiert wurde. Wenn Sie willkürliche Indizes (d. H. Keine rechteckige Scheibe) übergeben müssen, erhalten Sie keine Höchstgeschwindigkeit. – BrenBarn

+1

ja, benutze numpy 1.9 – seberg

+3

'np.multiply (A, A)' ist * elementweise * Multiplikation. Verwenden Sie 'np.dot (A, A)' für die Matrixmultiplikation. –

Antwort

1

Wenn ich versuche, Ihr Problem zu reproduzieren, sehe ich keinen so drastischen Effekt. Ich merke, dass abhängig von der Anzahl der ausgewählten Indizes die Indexierung sogar schneller als die Multiplikation sein kann.

>>> import numpy as np 
>>> np.__version__ 
Out[1]: '1.9.0' 
>>> N = 14000 
>>> A = np.random.random(size=[N, N]) 

>>> indices = np.sort(np.random.choice(np.arange(N), 0.9*N, replace=False)) 
>>> timeit A[np.ix_(indices, indices)] 
1 loops, best of 3: 1.02 s per loop 
>>> timeit A.take(indices, axis=0).take(indices, axis=1) 
1 loops, best of 3: 1.37 s per loop 
>>> timeit np.multiply(A,A) 
1 loops, best of 3: 748 ms per loop 

>>> indices = np.sort(np.random.choice(np.arange(N), 0.7*N, replace=False)) 
>>> timeit A[np.ix_(indices, indices)] 
1 loops, best of 3: 633 ms per loop 
>>> timeit A.take(indices, axis=0).take(indices, axis=1) 
1 loops, best of 3: 946 ms per loop 
>>> timeit np.multiply(A,A) 
1 loops, best of 3: 728 ms per loop 
Verwandte Themen