Jaki jest odpowiednik repmat MATLAB w NumPy

103

Chciałbym wykonać odpowiednik następującego kodu MATLAB przy użyciu numpy: repmat([1; 1], [1 1 1]). Jak miałbym to osiągnąć?

vernomcrp
źródło

Odpowiedzi:

103

Oto znacznie lepszy (oficjalny) link do NumPy dla użytkowników Matlaba - obawiam się, że matezaurus jest dość nieaktualny.

Numpy odpowiednikiem repmat(a, m, n)to tile(a, (m, n)).

Działa to z wieloma wymiarami i daje podobny wynik do Matlab. (Numpy daje tablicę wyjściową 3D, jak można się spodziewać - matlab z jakiegoś powodu daje wyjście 2D - ale zawartość jest taka sama).

Matlab:

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

ans =
     1
     1

Pyton:

In [46]: a = np.array([[1],[1]])
In [47]: np.tile(a, [1,1,1])
Out[47]: 
array([[[1],
        [1]]])
Robince
źródło
2
kiedy spróbuję size (repmat ([1; 1], [1,1,2])) otrzymuję ans = 2 1 2 [w matlab] ale w pythonie np.tile (a, [1,1,2]) .shape it get (1, 2, 2), chcę numpy dać wynik taki sam jak matlab
vernomcrp
2
np.tile (a [:, np.newaxis], [1,1,2]) - daje to samo. Problem polega ana tym, że kafelek awansuje do wymiaru argumentu kafelek przez poprzedzanie nowych osi, jeśli to konieczne. Wydaje się, że Matlab działa w drugą stronę. Podobnie, z kafelkami 4d będziesz potrzebować newaxis dwa razy ... więc np.tile(a[:,newaxis,newaxis],[1,2,3,4]) = size(repmat(a,[1 2 3 4]))zgodnie z wymaganiami ...
robince
17

Zwróć uwagę, że niektóre powody, dla których musisz używać repmat MATLAB, są rozwiązywane przez mechanizm nadawania NumPy , który pozwala wykonywać różne rodzaje matematyki z tablicami o podobnym kształcie. Więc jeśli masz, powiedzmy, tablicę 1600x1400x3 reprezentującą 3-kolorowy obraz, możesz (elementarnie) pomnożyć ją przez, [1.0 0.25 0.25]aby zmniejszyć ilość zieleni i niebieskiego w każdym pikselu. Aby uzyskać więcej informacji, zobacz powyższy link.

kwatford
źródło
2
Nie znaczy to, że Matlab może również wykonywać tę transmisję, jeśli używasz bsxfun.
gerrit
8

W ten sposób zrozumiałem to, trochę się majstrując. Cieszę się, że zostałem poprawiony i mam nadzieję, że to pomoże.

Powiedzmy, że masz macierz M składającą się z elementów 2x3. Ma to oczywiście dwa wymiary.


Nie widziałem różnicy między Matlabem a Pythonem, prosząc o manipulowanie macierzą wejściową wzdłuż wymiarów, które już ma macierz. Stąd te dwa polecenia

repmat(M,m,n) % matlab

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

są naprawdę równoważne dla macierzy rzędu 2 (dwa wymiary).


Sprawa jest sprzeczna z intuicją, gdy poprosisz o powtórzenie / kafelkowanie na większej liczbie wymiarów niż ma macierz wejściowa. Wracając do macierzy M rzędu drugiego i kształtu 2x3, wystarczy spojrzeć na to, co dzieje się z rozmiarem / kształtem macierzy wyjściowej. Powiedzmy, że kolejność manipulacji to teraz 1,1,2.

W Matlab

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

    2   3   2

skopiował pierwsze dwa wymiary (wiersze i kolumny) macierzy wejściowej i powtórzył to raz do nowego trzeciego wymiaru (to znaczy skopiował dwukrotnie). Zgodnie z nazewnictwem repmatmacierzy powtórzonych.

W Pythonie

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

zastosował inną procedurę, ponieważ przypuszczam, że sekwencja (1, 1, 2) jest odczytywana inaczej niż w Matlabie. Liczbę kopii w kierunku kolumn, wierszy i wymiaru poza płaszczyzną odczytuje się od prawej do lewej. Powstały obiekt ma inny kształt niż Matlab. Nie można już tego twierdzić repmati tilesą to instrukcje równoważne.


Aby tilezachowywać się tak repmat, w Pythonie trzeba się upewnić, że macierz wejściowa ma tyle wymiarów, ile elementów jest w sekwencji. Odbywa się to na przykład poprzez wstępne uwarunkowanie i utworzenie powiązanego obiektu N.

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

Następnie po stronie wejściowej mamy N.shape = (2,3,1)raczej niż M.shape = (2,3)i po stronie wyjściowej

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

co było odpowiedzią size(repmat(M,1,1,2)). Przypuszczam, że dzieje się tak dlatego, że poprowadziliśmy Pythona, aby dodać trzeci wymiar po prawej stronie (2,3), a nie po lewej stronie, dzięki czemu Python opracuje sekwencję (1,1,2) zgodnie z zamierzeniami Matlaba sposób czytania.

Element w [:,:,0]odpowiedź Pythona N będą zawierać te same wartości, jak element (:,:,1)odpowiedzi Matlab dla M .


Wreszcie, nie wydaje mi się, aby znaleźć odpowiednik dla repmatsytuacji, w których używa się produktu Kronecker

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

chyba że następnie warunkuję M w N jak powyżej. Twierdziłbym więc, że najbardziej ogólnym sposobem posunięcia się naprzód jest użycie sposobów np.newaxis.


Gra staje się trudniejsza, gdy weźmiemy pod uwagę macierz L rangi 3 (trzy wymiary) i prosty przypadek braku dodawania nowych wymiarów do macierzy wyjściowej. Te dwie pozornie równoważne instrukcje nie dadzą takich samych wyników

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

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

ponieważ wiersze, kolumny, kierunki poza płaszczyzną to (p, q, r) w Matlabie i (q, r, p) w Pythonie, co nie było widoczne w przypadku tablic typu rank-2. Tam trzeba być ostrożnym, a uzyskanie takich samych wyników w tych dwóch językach wymagałoby więcej wstępnych uwarunkowań.


Zdaję sobie sprawę, że to rozumowanie może nie być ogólne, ale tylko do tego stopnia mógłbym się nad tym zastanowić. Miejmy nadzieję, że zachęci to innych kolegów do poddania go trudniejszej próbie.

XavierStuvw
źródło
6

Poznaj zarówno tilei repeat.

x = numpy.arange(5)
print numpy.tile(x, 2)
print x.repeat(2)
Steve Tjoa
źródło
1

numpy.matlib ma funkcję repmat z interfejsem podobnym do funkcji Matlab

from numpy.matlib import repmat
repmat( np.array([[1],[1]]) , 1, 1)
e-malito
źródło
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]])
Żywe
źródło