Python Numpy – Crear matriz 2D donde la longitud está basada en un arreglo 1D.
Disculpe por el título confuso, pero no estoy seguro de cómo hacerlo más conciso. Aquí están mis requisitos:
arr1 = np.array([3,5,9,1])
arr2 = ?(arr1)
Entonces, arr2 sería:
[
[0,1,2,0,0,0,0,0,0],
[0,1,2,3,4,0,0,0,0],
[0,1,2,3,4,5,6,7,8],
[0,0,0,0,0,0,0,0,0]
]
No necesita variar según el máximo, la forma se conoce de antemano. Entonces, para comenzar, he podido obtener una forma de ceros:
arr2 = np.zeros((len(arr1),max_len))
Y luego, por supuesto, podría hacer un bucle for sobre arr1 de esta manera:
for i, elemento in enumerate(arr1):
arr2[i,0:elemento] = np.arange(elemento)
pero eso probablemente llevaría mucho tiempo y ambas dimensiones aquí son bastante grandes (arr1 tiene algunas millones de filas, max_len es alrededor de 500). ¿Hay alguna manera optimizada y limpia de hacer esto en numpy?
davy.ai
Sí, hay una forma más eficiente de lograr esto utilizando las capacidades de transmisión y vectorización de numpy. Aquí está el código para lograr la salida deseada:
La salida será:
Aquí hay una explicación de cómo funciona:
indices
es una matriz de forma(max_len,)
que contiene los valores de 0 amax_len-1
.arr1
para que tenga forma(len(arr1), 1)
para poder transmitirlo sobreindices
. Esto crea una matrizmask
de forma(len(arr1), max_len)
donde cada fila contiene valoresTrue
hasta el elemento correspondiente enarr1
y valoresFalse
para el resto.arr2
como una matriz de ceros con forma(len(arr1), max_len)
.mask
y los índicesindices
para asignar valores aarr2
. Aquí aprovechamos nuevamente la transmisión de numpy: la máscara se transmite sobre las columnas dearr2
, de modo que cada fila dearr2
se completa con los valores correspondientes deindices
.