Was sind die Unterschiede zwischen Numpy-Arrays und Matrizen? Welches soll ich verwenden?

345

Was sind die Vor- und Nachteile von jedem?

Nach allem, was ich gesehen habe, kann einer bei Bedarf als Ersatz für den anderen dienen. Sollte ich mir also die Mühe machen, beide zu verwenden, oder sollte ich mich nur an einen von ihnen halten?

Wird der Stil des Programms meine Wahl beeinflussen? Ich lerne maschinell mit Numpy, also gibt es zwar viele Matrizen, aber auch viele Vektoren (Arrays).

levesque
quelle
3
Ich habe nicht genügend Informationen, um eine Antwort zu rechtfertigen, aber was ich sagen kann, ist der Hauptunterschied die Implementierung der Multiplikation. Eine Matrix führt eine Matrix / Tensor-Multiplikation durch, während ein Array eine elementweise Multiplikation durchführt.
Mike Axiak
5
Python 3.5 hat den Infix @ -Operator für die Matrixmultiplikation (PEP 465) hinzugefügt, und NumPy 1.10 hat Unterstützung dafür hinzugefügt. Wenn Sie also Python 3.5+ und NumPy 1.10+ verwenden, können Sie einfach schreiben, A @ Banstatt A.dot(B), wo Aund Bsind 2Ds ndarray. Dies beseitigt den Hauptvorteil der Verwendung matrixvon ndarrayIMHO anstelle von einfachen s.
MiniQuark

Antworten:

396

Numpy- Matrizen sind streng zweidimensional, während Numpy- Arrays (ndarrays) N-dimensional sind. Matrixobjekte sind eine Unterklasse von ndarray, daher erben sie alle Attribute und Methoden von ndarrays.

Der Hauptvorteil von Numpy-Matrizen besteht darin, dass sie eine bequeme Notation für die Matrixmultiplikation bieten: Wenn a und b Matrizen sind, a*bist dies ihr Matrixprodukt.

import numpy as np

a = np.mat('4 3; 2 1')
b = np.mat('1 2; 3 4')
print(a)
# [[4 3]
#  [2 1]]
print(b)
# [[1 2]
#  [3 4]]
print(a*b)
# [[13 20]
#  [ 5  8]]

Andererseits unterstützt NumPy ab Python 3.5 die Infix-Matrix-Multiplikation mit dem @Operator, sodass Sie mit ndarrays in Python> = 3.5 den gleichen Komfort der Matrix-Multiplikation erzielen können.

import numpy as np

a = np.array([[4, 3], [2, 1]])
b = np.array([[1, 2], [3, 4]])
print(a@b)
# [[13 20]
#  [ 5  8]]

Sowohl Matrixobjekte als auch ndarrays müssen .Tdie Transponierte zurückgeben, aber Matrixobjekte müssen auch .Hfür die konjugierte Transponierung und .Ifür die Umkehrung.

Im Gegensatz dazu halten sich Numpy-Arrays konsequent an die Regel, dass Operationen elementweise angewendet werden (mit Ausnahme des neuen @Operators). Wenn also aund bnumpy Arrays sind, dann a*bwird das Array durch Multiplikation der Komponenten elementweise gebildet:

c = np.array([[4, 3], [2, 1]])
d = np.array([[1, 2], [3, 4]])
print(c*d)
# [[4 6]
#  [6 4]]

Um das Ergebnis der Matrixmultiplikation zu erhalten, verwenden Sie np.dot(oder @in Python> = 3.5, wie oben gezeigt):

print(np.dot(c,d))
# [[13 20]
#  [ 5  8]]

Der **Bediener verhält sich auch anders:

print(a**2)
# [[22 15]
#  [10  7]]
print(c**2)
# [[16  9]
#  [ 4  1]]

Da aes sich um eine Matrix handelt, wird a**2das Matrixprodukt zurückgegeben a*a. Da ces sich um ein ndarray handelt, wird ein ndarray zurückgegeben, c**2wobei jede Komponente elementweise quadriert wird.

Es gibt andere technische Unterschiede zwischen Matrixobjekten und ndarrays (was mit der np.ravelElementauswahl und dem Sequenzverhalten zu tun hat ).

Der Hauptvorteil von Numpy-Arrays besteht darin, dass sie allgemeiner sind als zweidimensionale Matrizen . Was passiert, wenn Sie ein dreidimensionales Array wünschen? Dann müssen Sie ein ndarray verwenden, kein Matrixobjekt. Das Erlernen der Verwendung von Matrixobjekten ist daher mehr Arbeit - Sie müssen Matrixobjektoperationen und Ndarray-Operationen lernen.

Das Schreiben eines Programms, das sowohl Matrizen als auch Arrays mischt, erschwert Ihr Leben, da Sie verfolgen müssen, um welche Art von Objekt es sich bei Ihren Variablen handelt, damit die Multiplikation nicht etwas zurückgibt, das Sie nicht erwarten.

Wenn Sie sich dagegen ausschließlich an ndarrays halten, können Sie alles tun, was Matrixobjekte können, und mehr, außer mit leicht unterschiedlichen Funktionen / Notationen.

Wenn Sie bereit sind, die visuelle Attraktivität der NumPy-Matrix-Produktnotation aufzugeben (die mit ndarrays in Python> = 3.5 fast genauso elegant erreicht werden kann), dann sind NumPy-Arrays meiner Meinung nach definitiv der richtige Weg.

PS. Natürlich haben Sie wirklich nicht eine auf Kosten des anderen zu wählen, da np.asmatrixund np.asarrayermöglicht es Ihnen , einen zum anderen (solange das Array 2-dimensional ist) zu konvertieren.


Es gibt eine Übersicht über die Unterschiede zwischen NumPy arraysvs NumPy matrixes hier .

unutbu
quelle
7
Für diejenigen, die sich fragen, kann mat**neine Matrix unelegant auf ein Array mitreduce(np.dot, [arr]*n)
askewchan
6
Oder einfachnp.linalg.matrix_power(mat, n)
Eric
Ich frage mich, ob Matrizen schneller wären ... Sie würden denken, sie müssen weniger Überprüfungen durchführen als ndarray.
PascalVKooten
1
Tatsächlich zeigen Timeit-Tests, dass ndarray-Operationen np.dot(array2, array2)schneller sind als matrix1*matrix2. Dies ist sinnvoll, da matrixes sich um eine Unterklasse von ndarray handelt, die spezielle Methoden wie überschreibt __mul__. matrix.__mul__Anrufenp.dot . Hier wird also Code wiederverwendet. Anstatt weniger Überprüfungen durchzuführen, matrix*matrixerfordert die Verwendung einen zusätzlichen Funktionsaufruf. Der Vorteil der Verwendung matrixliegt also in der rein syntaktischen und nicht in der besseren Leistung.
Unutbu
4 * 1 + 3 * 3, die Ihnen 13 geben, als Sie np.dot (c, d) getan haben, ist nicht wirklich ein Kreuzprodukt in Mathe genannt
PirateApp
92

Scipy.org empfiehlt die Verwendung von Arrays:

* 'Array' oder 'Matrix'? Welches soll ich verwenden? - Kurze Antwort

Verwenden Sie Arrays.

  • Sie sind der Standardtyp für Vektor / Matrix / Tensor von Numpy. Viele Numpy-Funktionen geben Arrays zurück, keine Matrizen.

  • Es gibt eine klare Unterscheidung zwischen elementweisen Operationen und linearen Algebraoperationen.

  • Sie können Standardvektoren oder Zeilen- / Spaltenvektoren verwenden, wenn Sie möchten.

Der einzige Nachteil der Verwendung des Array-Typs besteht darin, dass Sie zwei Tensoren (Skalarprodukt, Matrixvektormultiplikation usw.) verwenden müssen, dotanstatt sie *zu multiplizieren (zu reduzieren).

atomh33ls
quelle
11
Obwohl die akzeptierte Antwort mehr Informationen enthält, ist die eigentliche Antwort in der Tat zu bleiben ndarray. Das Hauptargument für die Verwendung matrixwäre, wenn Ihr Code schwer in linearer Algebra ist und bei allen Aufrufen der dotFunktion weniger klar aussehen würde . Dieses Argument wird jedoch in Zukunft verschwinden, da der @ -Operator zur Verwendung mit der Matrixmultiplikation akzeptiert wird (siehe PEP 465) . Dies erfordert Python 3.5 und die neueste Version von Numpy. Die Matrixklasse könnte in ferner Zukunft veraltet sein, daher ist es besser, ndarray für neuen Code zu verwenden ...
Bas Swinckels
6
Diese Seite vergisst gnädigerweise scipy.sparseMatrizen. Wenn Sie in Ihrem Code sowohl dichte als auch spärliche Matrizen verwenden, ist es viel einfacher, sich daran zu halten matrix.
David Nemeskey
3
Meiner Meinung nach besteht der Hauptnachteil von Arrays darin, dass das Spalten-Slicing flache Arrays zurückgibt, was verwirrend sein kann und mathematisch nicht wirklich solide ist. Dies führt auch zu dem wichtigen Nachteil, dass Numpy-Arrays nicht wie scipy.sparse-Matrizen behandelt werden können, während Numpy-Matrizen grundsätzlich frei mit spärlichen Matrizen ausgetauscht werden können. Etwas absurd in diesem Zusammenhang, dass scipy die Verwendung von Arrays empfiehlt und dann keine kompatiblen, spärlichen Arrays bereitstellt.
Radio Controlled
29

Nur um einen Fall zur Liste von unutbu hinzuzufügen.

Einer der größten praktischen Unterschiede zwischen numpy ndarrays und numpy Matrizen oder Matrixsprachen wie matlab besteht für mich darin, dass die Dimension bei Reduktionsoperationen nicht erhalten bleibt. Matrizen sind immer 2d, während der Mittelwert eines Arrays beispielsweise eine Dimension weniger hat.

Zum Beispiel erniedrigen Zeilen einer Matrix oder eines Arrays:

mit Matrix

>>> m = np.mat([[1,2],[2,3]])
>>> m
matrix([[1, 2],
        [2, 3]])
>>> mm = m.mean(1)
>>> mm
matrix([[ 1.5],
        [ 2.5]])
>>> mm.shape
(2, 1)
>>> m - mm
matrix([[-0.5,  0.5],
        [-0.5,  0.5]])

mit Array

>>> a = np.array([[1,2],[2,3]])
>>> a
array([[1, 2],
       [2, 3]])
>>> am = a.mean(1)
>>> am.shape
(2,)
>>> am
array([ 1.5,  2.5])
>>> a - am #wrong
array([[-0.5, -0.5],
       [ 0.5,  0.5]])
>>> a - am[:, np.newaxis]  #right
array([[-0.5,  0.5],
       [-0.5,  0.5]])

Ich denke auch, dass das Mischen von Arrays und Matrizen zu vielen "glücklichen" Debugging-Stunden führt. Scipy.sparse-Matrizen sind jedoch immer Matrizen in Bezug auf Operatoren wie Multiplikation.

Josef
quelle