In numpy
kehren einige der Operationen in Form zurück (R, 1)
, andere (R,)
. Dies macht die Matrixmultiplikation mühsamer, da explizit reshape
erforderlich ist. M
Wenn wir beispielsweise bei einer Matrix angeben möchten, numpy.dot(M[:,0], numpy.ones((1, R)))
wo R
sich die Anzahl der Zeilen befindet (das gleiche Problem tritt natürlich auch spaltenweise auf). Wir werden matrices are not aligned
Fehler bekommen , da M[:,0]
es in Form ist, (R,)
aber numpy.ones((1, R))
in Form ist (1, R)
.
Meine Fragen sind also:
Was ist der Unterschied zwischen Form
(R, 1)
und(R,)
. Ich weiß buchstäblich, dass es eine Liste von Zahlen und eine Liste von Listen ist, in denen alle Listen nur eine Zahl enthalten. Ich frage mich nur, warum nichtnumpy
so gestalten , dass die Form bevorzugt wird,(R, 1)
anstatt die(R,)
Matrixmultiplikation zu vereinfachen.Gibt es bessere Möglichkeiten für das obige Beispiel? Ohne explizite Umformung wie folgt:
numpy.dot(M[:,0].reshape(R, 1), numpy.ones((1, R)))
Antworten:
1. Die Bedeutung von Formen in NumPy
Sie schreiben: "Ich weiß buchstäblich, dass es eine Liste von Zahlen und eine Liste von Listen ist, in denen alle Listen nur eine Zahl enthalten", aber das ist ein wenig wenig hilfreich, um darüber nachzudenken.
Der beste Weg, um über NumPy-Arrays nachzudenken, besteht darin, dass sie aus zwei Teilen bestehen, einem Datenpuffer, der nur ein Block von Rohelementen ist, und einer Ansicht die beschreibt, wie der Datenpuffer interpretiert wird.
Wenn wir beispielsweise ein Array mit 12 Ganzzahlen erstellen:
a
Besteht dann aus einem Datenpuffer, der ungefähr so angeordnet ist:und eine Ansicht, die beschreibt, wie die Daten zu interpretieren sind:
Hier bedeutet die Form,
(12,)
dass das Array durch einen einzelnen Index indiziert wird, der von 0 bis 11 läuft. Wenn wir diesen einzelnen Indexi
kennzeichnen,a
sieht das Array konzeptionell folgendermaßen aus:Wenn wir ein Array umformen , ändert dies nichts am Datenpuffer. Stattdessen wird eine neue Ansicht erstellt, die eine andere Art der Interpretation der Daten beschreibt. So danach:
Das Array
b
hat den gleichen Datenpuffer wiea
, wird jedoch jetzt durch zwei Indizes indiziert , die von 0 bis 2 bzw. 0 bis 3 laufen. Wenn wir die beiden Indizesi
und beschriftenj
,b
sieht das Array folgendermaßen aus:was bedeutet, dass:
Sie können sehen, dass sich der zweite Index schnell und der erste Index langsam ändert. Wenn Sie dies umgekehrt bevorzugen, können Sie den folgenden
order
Parameter angeben :was zu einem Array führt, das wie folgt indiziert ist:
was bedeutet, dass:
Es sollte nun klar sein, was es für ein Array bedeutet, eine Form mit einer oder mehreren Dimensionen der Größe 1 zu haben. Nachher:
Das Array
d
wird durch zwei Indizes indiziert, von denen der erste von 0 bis 11 läuft und der zweite Index immer 0 ist:und so:
Eine Dimension der Länge 1 ist (in gewissem Sinne) "frei", daher hindert Sie nichts daran, in die Stadt zu gehen:
Geben eines wie folgt indizierten Arrays:
und so:
Weitere Informationen zur Implementierung von Arrays finden Sie in der Dokumentation zu NumPy-Interna .
2. Was ist zu tun?
Schon seit
numpy.reshape
nur eine neue Ansicht erstellt wird, sollten Sie keine Angst haben, sie bei Bedarf zu verwenden. Es ist das richtige Werkzeug, wenn Sie ein Array auf andere Weise indizieren möchten.Bei einer langen Berechnung ist es jedoch normalerweise möglich, Arrays mit der "richtigen" Form zu konstruieren und so die Anzahl der Umformen und Transponierungen zu minimieren. Aber ohne den tatsächlichen Kontext zu sehen, der zur Notwendigkeit einer Umformung geführt hat, ist es schwer zu sagen, was geändert werden sollte.
Das Beispiel in Ihrer Frage lautet:
das ist aber nicht realistisch. Erstens dieser Ausdruck:
berechnet das Ergebnis einfacher. Zweitens, hat Spalte 0 wirklich etwas Besonderes? Vielleicht brauchen Sie tatsächlich:
quelle
newaxis
Sie diese Option, wenn Sie eine andere Achse benötigen, z. B.a[:, j, np.newaxis]
diej
dritte Spalte vona
unda[np.newaxis, i]
diei
dritte Zeile.(R, )
Fall ist die Form vonndarray
ein Tupel mit einzelnen Elementen, das von Python mit einem nachgestellten Komma gedruckt wird. Ohne das zusätzliche Komma wäre ein Ausdruck in Klammern nicht eindeutig . Andarray
mit einer einzelnen Dimension kann jedoch als Spaltenvektor der Länge betrachtet werdenR
. In dem(R, 1)
Fall hat das Tupel zwei Elemente, kann also als Zeilenvektor (oder als Matrix mit 1 Zeile Länge) betrachtet werdenR
.Der Unterschied zwischen
(R,)
und(1,R)
ist buchstäblich die Anzahl der Indizes, die Sie verwenden müssen.ones((1,R))
ist ein 2-D-Array, das zufällig nur eine Zeile enthält.ones(R)
ist ein Vektor. Wenn es für die Variable nicht sinnvoll ist, mehr als eine Zeile / Spalte zu haben, sollten Sie im Allgemeinen einen Vektor verwenden, keine Matrix mit einer Singleton-Dimension.Für Ihren speziellen Fall gibt es mehrere Optionen:
1) Machen Sie einfach das zweite Argument zu einem Vektor. Folgendes funktioniert gut:
2) Wenn Sie matlabähnliche Matrixoperationen wünschen, verwenden Sie
matrix
stattdessen die Klassendarray
. Alle Matrizen werden zu 2D-Arrays gezwungen, und der Operator*
führt die Matrixmultiplikation anstelle der Elemente durch (Sie benötigen also keinen Punkt). Nach meiner Erfahrung ist dies mehr Mühe, als es wert ist, aber es kann schön sein, wenn Sie an Matlab gewöhnt sind.quelle
matrix
Unterricht ansehen . Was ist das Problem für diematrix
Klasse BTW?matrix
ist, dass es sich nur um 2D handelt und dass Funktionen, für die geschrieben wurde,ndarray
möglicherweise fehlschlagen, wenn sie auf a verwendet werden , da sie den Operator '*' überladenmatrix
.Die Form ist ein Tupel. Wenn es nur eine Dimension gibt, ist die Form eine Zahl und nach einem Komma nur leer. Bei mehr als 2 Dimensionen wird nach allen Kommas eine Zahl angezeigt.
quelle
Für die Basis-Array-Klasse sind 2d-Arrays nicht spezieller als 1d- oder 3d-Arrays. Es gibt einige Operationen, bei denen die Dimensionen erhalten bleiben, andere, die sie reduzieren, andere kombinieren oder sogar erweitern.
Andere Ausdrücke, die dasselbe Array ergeben
MATLAB begann mit nur 2D-Arrays. Neuere Versionen erlauben mehr Dimensionen, behalten jedoch die Untergrenze von 2 bei. Sie müssen jedoch immer noch auf den Unterschied zwischen einer Zeilenmatrix und einer Spalte mit der Form
(1,3)
v achten(3,1)
. Wie oft hast du geschrieben[1,2,3].'
? Ich wollte schreibenrow vector
undcolumn vector
, aber mit dieser 2d-Einschränkung gibt es in MATLAB keine Vektoren - zumindest nicht im mathematischen Sinne von Vektor als 1d.Haben Sie sich angesehen
np.atleast_2d
(auch _1d und _3d Versionen)?quelle
1) Der Grund , nicht eine Form zu bevorzugen
(R, 1)
über(R,)
ist , dass es Dinge unnötig kompliziert. Außerdem, warum sollte es vorzuziehen sein,(R, 1)
standardmäßig eine Form für einen Vektor der Länge R anstelle von zu haben(1, R)
? Es ist besser, es einfach zu halten und explizit zu sein, wenn Sie zusätzliche Abmessungen benötigen.2) In Ihrem Beispiel berechnen Sie ein äußeres Produkt, sodass Sie dies ohne
reshape
Aufruf tun können , indem Sie Folgendes verwendennp.outer
:quelle
M[:,0]
erhält im Wesentlichen alle Zeilen mit dem ersten Element, daher ist es sinnvoller,(R, 1)
als zu haben(1, R)
. 2) Es ist nicht immer durch einennp.outer
Punkt für eine Matrix in Form (1, R) und dann (R, 1) ersetzbar .matrix
Objekt zu verwenden. 2) Eigentlichnp.outer
funktioniert unabhängig davon , ob die Formen sind(1, R)
,(R, 1)
oder eine Kombination aus beiden.Hier gibt es bereits viele gute Antworten. Aber für mich war es schwierig, ein Beispiel zu finden, bei dem die Form oder das Array das gesamte Programm beschädigen kann.
Also hier ist der eine:
Dies wird mit Fehler fehlschlagen:
aber wenn wir hinzufügen
reshape
zua
:das funktioniert richtig!
quelle