web-dev-qa-db-fra.com

Comment convertir une liste de tableaux numpy en tableau numpy unique?

Supposons que j'ai

LIST = [[array([1, 2, 3, 4, 5]), array([1, 2, 3, 4, 5],[1,2,3,4,5])] # inner lists are numpy arrays

J'essaie de me convertir;

array([[1, 2, 3, 4, 5],
       [1, 2, 3, 4, 5],
       [1, 2, 3, 4, 5])

Je le résout par itération sur vstack en ce moment mais il est vraiment lent pour une liste particulièrement volumineuse

Que proposez-vous pour le meilleur moyen efficace?

57
erogol

En général, vous pouvez concaténer toute une séquence de tableaux le long de n'importe quel axe:

numpy.concatenate( LIST, axis=0 )

mais vous do devez vous préoccuper de la forme et de la dimensionnalité de chaque tableau de la liste (pour une sortie 3x5 en 2 dimensions, vous devez vous assurer que ce sont tous des tableaux n-par-5 en 2 dimensions déjà). Si vous souhaitez concaténer des tableaux à une dimension en tant que lignes d'une sortie à deux dimensions, vous devez développer leur dimensionnalité.

Comme le souligne la réponse de Jorge, il existe également la fonction stack, introduite dans numpy 1.10:

numpy.stack( LIST, axis=0 )

Cela prend une approche complémentaire: il crée une nouvelle vue de chaque tableau en entrée et ajoute une dimension supplémentaire (dans ce cas, à gauche, de sorte que chaque tableau 1D n- élément devienne un 1-by -n tableau 2D) avant la concaténation. Cela ne fonctionnera que si toutes les baies d'entrée ont la même forme, même le long de l'axe de concaténation.

vstack (ou équivalent row_stack) est souvent une solution plus facile à utiliser car elle nécessite une séquence de tableaux à 1 et/ou 2 dimensions et étend automatiquement la dimensionnalité si nécessaire et uniquement si nécessaire avant de concaténer toute la liste. Lorsqu'une nouvelle dimension est requise, elle est ajoutée à gauche. Encore une fois, vous pouvez concaténer toute une liste à la fois sans avoir à itérer:

numpy.vstack( LIST )

Ce comportement flexible est également présenté par le raccourci syntaxique numpy.r_[ array1, ...., arrayN ] (notez les crochets). C'est bon pour concaténer quelques tableaux nommés explicitement, mais cela ne convient pas dans votre cas, car cette syntaxe n'acceptera pas une séquence de tableaux, comme votre LIST.

Il y a aussi une fonction analogue column_stack et raccourci c_[...], pour une pile horizontale (ainsi que pour une colonne), ainsi qu'une fonction presque - analogue hstack— bien que, pour une raison quelconque, Ce dernier est moins flexible (il est plus strict quant à la dimensionnalité des tableaux d’entrée et tente de concaténer les tableaux 1-D de bout en bout au lieu de les traiter comme des colonnes).

Enfin, dans le cas particulier de l’empilement vertical de matrices 1-D, fonctionne également:

numpy.array( LIST )

... car les tableaux peuvent être construits à partir d'une séquence d'autres tableaux, ce qui ajoute une nouvelle dimension au début.

83
jez

A partir de NumPy version 1.10, nous avons la méthode pile . Il peut empiler des tableaux de n'importe quelle dimension (tous égaux):

# List of arrays.
L = [np.random.randn(5,4,2,5,1,2) for i in range(10)]

# Stack them using axis=0.
M = np.stack(L)
M.shape # == (10,5,4,2,5,1,2)
np.all(M == L) # == True

M = np.stack(L, axis=1)
M.shape # == (5,10,4,2,5,1,2)
np.all(M == L) # == False (Don't Panic)

# This are all true    
np.all(M[:,0,:] == L[0]) # == True
all(np.all(M[:,i,:] == L[i]) for i in range(10)) # == True

Prendre plaisir,

3
Jorge E. Cardona