Pregunta ¿Cuál es el equivalente del repmat de MATLAB en NumPy?


Me gustaría ejecutar el equivalente del siguiente código MATLAB usando NumPy: repmat([1; 1], [1 1 1]). ¿Cómo podría lograr esto?


76
2017-11-12 12:20


origen


Respuestas:


Aquí hay un mucho mejor (oficial) NumPy para usuarios de Matlab link - Me temo que el mathesaurus está bastante desactualizado.

El numpy equivalente de repmat(a, m, n) es tile(a, (m, n)).

Esto funciona con múltiples dimensiones y da un resultado similar al de matlab. (Numpy da una matriz de salida en 3D como era de esperar - matlab por alguna razón da salida 2d - pero el contenido es el mismo).

Matlab:

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

ans =
     1
     1

Pitón:

In [46]: a = np.array([[1],[1]])
In [47]: np.tile(a, [1,1,1])
Out[47]: 
array([[[1],
        [1]]])

82
2017-11-12 18:36



Tenga en cuenta que algunas de las razones por las que necesitaría usar el repmat de MATLAB están a cargo de NumPy's radiodifusión mecanismo, que le permite hacer varios tipos de matemática con matrices de forma similar. Entonces, si tuviera, por ejemplo, una matriz de 1600x1400x3 que representara una imagen de 3 colores, podría (elemento) multiplicarla por [1.0 0.25 0.25] para reducir la cantidad de verde y azul en cada píxel. Vea el enlace de arriba para más información.


16
2017-11-12 13:24



Ver NumPy para usuarios de Matlab.

Matlab:

repmat(a, 2, 3)

Numpy:

numpy.kron(numpy.ones((2,3)), a)

9
2017-11-12 13:09



Sepa ambos tile y repeat.

x = numpy.arange(5)
print numpy.tile(x, 2)
print x.repeat(2)

5
2018-01-19 23:52



Así es como lo entendí de un poco de tiddling alrededor. Feliz de ser corregido y espero que esto ayude.

Digamos que tienes una matriz METRO de 2x3 elementos. Esto tiene dos dimensiones, obviamente.


No pude ver ninguna diferencia entre Matlab y Python al pedir manipular la matriz de entrada a lo largo de las dimensiones que ya tiene la matriz. Por lo tanto, los dos comandos

repmat(M,m,n) % matlab

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

son realmente equivalentes para una matriz de rango 2 (dos dimensiones).


Las cosas van contraintuitivas cuando se pregunta por repetición / mosaico en más dimensiones de las que tiene la matriz de entrada. Volviendo a la matriz M del rango dos y la forma 2x3, basta con observar qué sucede con el tamaño / forma de la matriz de salida. Digamos que la secuencia de manipulación ahora es 1,1,2.

En Matlab

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

    2   3   2

ha copiado las dos primeras dimensiones (filas y columnas) de la matriz de entrada y lo ha repetido una vez en una tercera dimensión nueva (copiado dos veces, es decir). Fiel a la denominación repmat para repetir la matriz.

En Python

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

ha aplicado un procedimiento diferente ya que, supongo, la secuencia (1,1,2) se lee de forma diferente que en Matlab. La cantidad de copias en la dirección de las columnas, las filas y la dimensión fuera del plano se leen de derecha a izquierda. El objeto resultante tiene una forma diferente de Matlab. Uno ya no puede afirmar eso repmat y tile son instrucciones equivalentes.


Para obtener tile comportarse como repmat, en Python uno tiene que asegurarse de que la matriz de entrada tenga tantas dimensiones como los elementos estén en la secuencia. Esto se hace, por ejemplo, mediante un pequeño preacondicionamiento y creando un objeto relacionado norte

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

Entonces, en el lado de entrada uno tiene N.shape = (2,3,1) más bien que M.shape = (2,3) y en el lado de salida

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

cual fue la respuesta de size(repmat(M,1,1,2)). Supongo que esto se debe a que hemos guiado a Python para que agregue la tercera dimensión a la derecha de (2,3) en lugar de a la izquierda, de modo que Python resuelva la secuencia (1,1,2) como estaba previsto en el Matlab forma de leerlo.

El elemento en [:,:,0] en la respuesta de Python para norte contendrá los mismos valores que el elemento (:,:,1) la respuesta de Matlab para METRO.


Finalmente, parece que no puedo encontrar un equivalente para repmat cuando uno usa el producto Kronecker fuera de

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

a menos que yo precondicione METRO dentro norte como anteriormente. Entonces, yo diría que la forma más general de seguir adelante es utilizar los modos de np.newaxis.


El juego se vuelve más complicado cuando consideramos una matriz L de rango 3 (tres dimensiones) y el caso simple de que no se agreguen nuevas dimensiones en la matriz de salida. Estas dos instrucciones aparentemente equivalentes no producirán los mismos resultados

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

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

porque la fila, la columna, las direcciones fuera del plano son (p, q, r) en Matlab y (q, r, p) en Python, que no era visible con los arrays de rango 2. Allí, hay que tener cuidado y obtener los mismos resultados con los dos idiomas requeriría más preacondicionamiento.


Soy consciente de que este razonamiento bien puede no ser general, pero podría resolverlo solo hasta aquí. Con suerte, esto invita a otros compañeros a someterlo a una prueba más dura.


4
2018-03-27 19:48



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]])

0
2017-07-26 09:32