Was ist das Äquivalent von MATLABs Repmat in NumPy?

103

Ich möchte das Äquivalent des folgenden MATLAB-Codes mit NumPy ausführen : repmat([1; 1], [1 1 1]). Wie würde ich das erreichen?

vernomcrp
quelle

Antworten:

103

Hier ist ein viel besserer (offizieller) NumPy für Matlab-Benutzer- Link - ich fürchte, der Mathesaurus ist ziemlich veraltet.

Das numpy-Äquivalent von repmat(a, m, n)ist tile(a, (m, n)).

Dies funktioniert mit mehreren Dimensionen und ergibt ein ähnliches Ergebnis wie matlab. (Numpy liefert ein 3D-Ausgabearray, wie Sie es erwarten würden - Matlab liefert aus irgendeinem Grund eine 2D-Ausgabe - aber der Inhalt ist der gleiche).

Matlab:

>> repmat([1;1],[1,1,1])

ans =
     1
     1

Python:

In [46]: a = np.array([[1],[1]])
In [47]: np.tile(a, [1,1,1])
Out[47]: 
array([[[1],
        [1]]])
Robince
quelle
2
Wenn ich die Größe versuche (repmat ([1; 1], [1,1,2])), wird ans = 2 1 2 [in matlab], aber in python np.tile (a, [1,1,2]) .shape es bekommen (1, 2, 2), ich möchte numpy geben Ergebnis das gleiche wie matlab
vernomcrp
2
np.tile (a [:, np.newaxis], [1,1,2]) - es gibt das gleiche. Das Problem besteht darin, dass Kacheln ain die Dimension des Kachelarguments befördert werden, indem bei Bedarf neue Achsen vorangestellt werden . Matlab scheint anders zu funktionieren. In ähnlicher Weise benötigen Sie bei 4d-Kacheln zweimal eine neue Achse ... also np.tile(a[:,newaxis,newaxis],[1,2,3,4]) = size(repmat(a,[1 2 3 4]))nach Bedarf ...
Robince
17

Beachten Sie, dass einige der Gründe, die Sie für die Verwendung von MATLABs Repmat benötigen, von NumPys Rundfunk berücksichtigt werden Mechanismus , mit dem Sie verschiedene Arten von Berechnungen mit Arrays ähnlicher Form durchführen können. Wenn Sie also beispielsweise ein 1600 x 1400 x 3-Array haben, das ein dreifarbiges Bild darstellt, können Sie es (elementweise) multiplizieren [1.0 0.25 0.25], um die Menge an Grün und Blau an jedem Pixel zu verringern. Weitere Informationen finden Sie unter dem obigen Link.

Kwatford
quelle
2
Nicht, dass Matlab diese Übertragung auch durchführen kann, wenn Sie sie verwenden bsxfun.
Gerrit
8

So habe ich es verstanden, weil ich ein bisschen herumgespielt habe. Ich bin froh, korrigiert zu werden und hoffe, dass dies hilft.

Angenommen, Sie haben eine Matrix M mit 2x3 Elementen. Dies hat offensichtlich zwei Dimensionen.


Ich konnte keinen Unterschied zwischen Matlab und Python feststellen, als ich darum bat, die Eingabematrix entlang der Dimensionen zu manipulieren, die die Matrix bereits hat. Also die beiden Befehle

repmat(M,m,n) % matlab

np.tile(M,(m,n)) # python

sind wirklich äquivalent für eine Matrix von Rang 2 (zwei Dimensionen).


Die Angelegenheit wird kontraintuitiv, wenn Sie nach Wiederholungen / Kacheln über mehr Dimensionen als die Eingabematrix fragen. Zurück zur Matrix M von Rang zwei und Form 2x3 ist es ausreichend zu betrachten, was mit der Größe / Form der Ausgabematrix passiert. Angenommen, die Reihenfolge für die Manipulation ist jetzt 1,1,2.

In Matlab

> size(repmat(M,1,1,2))
ans =

    2   3   2

Es hat die ersten beiden Dimensionen (Zeilen und Spalten) der Eingabematrix kopiert und diese einmal in eine neue dritte Dimension wiederholt (dh zweimal kopiert). Getreu der Benennungrepmat für die Wiederholungsmatrix.

In Python

>>> np.tile(M,(1,1,2)).shape
(1, 2, 6)

Es wurde ein anderes Verfahren angewendet, da die Sequenz (1,1,2) vermutlich anders gelesen wird als in Matlab. Die Anzahl der Kopien in Richtung der Spalten, Zeilen und der Bemaßung außerhalb der Ebene wird von rechts nach links gelesen. Das resultierende Objekt hat eine andere Form als Matlab. Man kann das nicht mehr behaupten repmatund tilesind gleichwertige Anweisungen.


Um sich so tilezu verhalten repmat, muss man in Python sicherstellen, dass die Eingabematrix so viele Dimensionen hat, wie sich die Elemente in der Sequenz befinden. Dies geschieht zum Beispiel durch ein wenig Vorkonditionieren und Erstellen eines verwandten Objekts N.

N = M[:,:,np.newaxis]

Dann hat man auf der Eingangsseite N.shape = (2,3,1)eher als M.shape = (2,3)und auf der Ausgangsseite

>>> np.tile(N,(1,1,2)).shape
(2, 3, 2)

Das war die Antwort von size(repmat(M,1,1,2)) . Ich nehme an, dies liegt daran, dass wir Python angewiesen haben, die dritte Dimension rechts von (2,3) und nicht links davon hinzuzufügen, damit Python die Sequenz (1,1,2) so ausarbeitet, wie sie im Matlab beabsichtigt war Art, es zu lesen.

Das Element in [:,:,0]der Python Antwort für N die gleichen Werte wie das Element enthält (:,:,1)die Matlab Antwort für M .


Schließlich kann ich anscheinend kein Äquivalent finden, repmatwenn man das Kronecker-Produkt aus verwendet

>>> np.kron(np.ones((1,1,2)),M).shape
(1, 2, 6)

es sei denn, ich setze dann M wie oben in N voraus. Daher würde ich argumentieren, dass der allgemeinste Weg, weiterzumachen, darin besteht, die Wege von zu verwenden np.newaxis.


Das Spiel wird schwieriger, wenn wir eine Matrix L mit Rang 3 (drei Dimensionen) und den einfachen Fall betrachten, dass der Ausgabematrix keine neuen Dimensionen hinzugefügt werden. Diese beiden scheinbar gleichwertigen Anweisungen führen nicht zu denselben Ergebnissen

repmat(L,p,q,r) % matlab

np.tile(L,(p,q,r)) # python

weil die Zeilen-, Spalten- und außerhalb der Ebene liegenden Richtungen in Matlab (p, q, r) und in Python (q, r, p) sind, was bei Rang-2-Arrays nicht sichtbar war. Dort muss man vorsichtig sein und die gleichen Ergebnisse mit den beiden Sprachen zu erzielen, würde mehr Vorkonditionierung erfordern.


Ich bin mir bewusst, dass diese Argumentation vielleicht nicht allgemein ist, aber ich könnte sie nur so weit herausarbeiten. Hoffentlich lädt dies andere Leute ein, es auf eine härtere Probe zu stellen.

XavierStuvw
quelle
6

Kennen Sie beide tileund repeat.

x = numpy.arange(5)
print numpy.tile(x, 2)
print x.repeat(2)
Steve Tjoa
quelle
1

numpy.matlib hat eine repmat- Funktion mit einer ähnlichen Schnittstelle wie die matlab-Funktion

from numpy.matlib import repmat
repmat( np.array([[1],[1]]) , 1, 1)
e-malito
quelle
0
>>> import numpy as np

>>> np.repeat(['a','b'], [2,5])

array(['a', 'a', 'b', 'b', 'b', 'b', 'b'], dtype='<U1')

>>> np.repeat([1,2], [2,5])

array([1, 1, 2, 2, 2, 2, 2])

>>> np.repeat(np.array([1,2]), [3]).reshape(2,3)

array([[1, 1, 1],
       [2, 2, 2]])

>>> np.repeat(np.array([1,2]), [2,4]).reshape(3,2)

array([[1, 1],
       [2, 2],
       [2, 2]])

>>> np.repeat(np.matrix('1 2; 3 4'), [2]).reshape(4,2)

matrix([[1, 1],
        [2, 2],
        [3, 3],
        [4, 4]])
Shivid
quelle