2011-10-05 9 views
9

quiero repetir elementos de una matriz a lo largo del eje 0 y el eje 1 para M y N veces respectivamente:¿Cómo se repiten elementos de una matriz a lo largo de dos ejes?

import numpy as np 

a = np.arange(12).reshape(3, 4) 
b = a.repeat(2, 0).repeat(2, 1) 
print(b) 

[[ 0 0 1 1 2 2 3 3] 
[ 0 0 1 1 2 2 3 3] 
[ 4 4 5 5 6 6 7 7] 
[ 4 4 5 5 6 6 7 7] 
[ 8 8 9 9 10 10 11 11] 
[ 8 8 9 9 10 10 11 11]] 

Esto funciona, pero quiero saber ¿Hay mejores métodos sin crear una matriz temporal.

+1

También vea las respuestas dadas en [esta publicación] (http://stackoverflow.com/q/32846846/2566083) usando kron, repeat y stride_tricks junto con el análisis de velocidad. – mlh3789

Respuesta

6

Usted podría utilizar el producto de Kronecker, ver numpy.kron:

>>> a = np.arange(12).reshape(3,4) 
>>> print np.kron(a, np.ones((2,2), dtype=a.dtype)) 
[[ 0 0 1 1 2 2 3 3] 
[ 0 0 1 1 2 2 3 3] 
[ 4 4 5 5 6 6 7 7] 
[ 4 4 5 5 6 6 7 7] 
[ 8 8 9 9 10 10 11 11] 
[ 8 8 9 9 10 10 11 11]] 

Su método original está bien también, sin embargo!

2

Otra solución es usar as_strided. kron es mucho más lento que usar repeat dos veces. He encontrado que as_strided es mucho más rápido que un doble repeat en muchos casos (matrices pequeñas [< 250x250] con solo una duplicación en cada dimensión as_strided fue más lento). El truco as_strided es el siguiente:

a = arange(1000000).reshape((1000, 1000)) # dummy data 

from numpy.lib.stride_tricks import as_strided 
N, M = 4,3 # number of time to replicate each point in each dimension 
H, W = a.shape 
b = as_strided(a, (H, N, W, M), (a.strides[0], 0, a.strides[1], 0)).reshape((H*N, W*M)) 

Esto funciona mediante el uso de pasos de longitud 0 numpy que hace que leer el mismo valor varias veces (hasta que llega a la siguiente dimensión). El reshape final copia los datos, pero solo una vez a diferencia de usar un doble repeat que copiará los datos dos veces.

+1

[Aquí está el enlace] (https://stackoverflow.com/a/32848377/3923281) a la solución donde se propuso 'as_strided', junto con los tiempos ;-) –

Cuestiones relacionadas