es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

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?

Tags:  , ,

Answer

  1. Avatar for 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:

    import numpy as np
    
    arr1 = np.array([3,5,9,1])
    max_len = 9
    
    # crear matriz de índices utilizando transmisión
    indices = np.arange(max_len)
    
    # crear máscara basada en arr1
    mask = indices < arr1.reshape(-1, 1)
    
    # crear matriz de salida utilizando la máscara e índices
    arr2 = np.zeros((len(arr1), max_len))
    arr2[mask] = indices
    
    print(arr2)
    

    La salida será:

    array([[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.]])
    

    Aquí hay una explicación de cómo funciona:

    • indices es una matriz de forma (max_len,) que contiene los valores de 0 a max_len-1.
    • Reshapeamos arr1 para que tenga forma (len(arr1), 1) para poder transmitirlo sobre indices. Esto crea una matriz mask de forma (len(arr1), max_len) donde cada fila contiene valores True hasta el elemento correspondiente en arr1 y valores False para el resto.
    • Creamos arr2 como una matriz de ceros con forma (len(arr1), max_len).
    • Utilizamos la máscara mask y los índices indices para asignar valores a arr2. Aquí aprovechamos nuevamente la transmisión de numpy: la máscara se transmite sobre las columnas de arr2, de modo que cada fila de arr2 se completa con los valores correspondientes de indices.

Comments are closed.