212 votes

Comment aplatir seulement certaines dimensions d'un tableau numpy

Existe-t-il un moyen rapide de "sous aplatir" ou d'aplatir seulement certaines des premières dimensions d'un tableau numpy ?

Par exemple, étant donné un tableau numpy de dimensions (50,100,25) les dimensions résultantes seront les suivantes (5000,25)

196voto

Alexander Points 1624

Jetez un coup d'œil à numpy.reshape .

>>> arr = numpy.zeros((50,100,25))
>>> arr.shape
# (50, 100, 25)

>>> new_arr = arr.reshape(5000,25)
>>> new_arr.shape   
# (5000, 25)

# One shape dimension can be -1. 
# In this case, the value is inferred from 
# the length of the array and remaining dimensions.
>>> another_arr = arr.reshape(-1, arr.shape[-1])
>>> another_arr.shape
# (5000, 25)

111voto

Peter Points 121

Une légère généralisation de la réponse d'Alexander - np.reshape peut prendre -1 comme argument, ce qui signifie "taille totale du tableau divisée par le produit de toutes les autres dimensions listées" :

Par exemple, pour aplatir toutes les dimensions sauf la dernière :

>>> arr = numpy.zeros((50,100,25))
>>> new_arr = arr.reshape(-1, arr.shape[-1])
>>> new_arr.shape
# (5000, 25)

64voto

KeithWM Points 448

Une légère généralisation de la réponse de Peter - vous pouvez spécifier une plage sur la forme du tableau original si vous voulez aller au-delà des tableaux à trois dimensions.

par exemple, pour aplatir tout sauf le dernier deux dimensions :

arr = numpy.zeros((3, 4, 5, 6))
new_arr = arr.reshape(-1, *arr.shape[-2:])
new_arr.shape
# (12, 5, 6)

EDIT : Une légère généralisation de ma réponse précédente - vous pouvez, bien sûr, également spécifier une plage au début de la reshape :

arr = numpy.zeros((3, 4, 5, 6, 7, 8))
new_arr = arr.reshape(*arr.shape[:2], -1, *arr.shape[-2:])
new_arr.shape
# (3, 4, 30, 7, 8)

4voto

mario23 Points 322

Une autre approche consiste à utiliser numpy.resize() comme dans :

In [37]: shp = (50,100,25)
In [38]: arr = np.random.random_sample(shp)
In [45]: resized_arr = np.resize(arr, (np.prod(shp[:2]), shp[-1]))
In [46]: resized_arr.shape
Out[46]: (5000, 25)

# sanity check with other solutions
In [47]: resized = np.reshape(arr, (-1, shp[-1]))
In [48]: np.allclose(resized_arr, resized)
Out[48]: True

2voto

Sherman Points 67

numpy.vstack est parfait pour cette situation

import numpy as np
arr = np.ones((50,100,25))
np.vstack(arr).shape
> (5000, 25)

Je préfère utiliser stack , vstack o hstack sur reshape parce que reshape se contente de balayer les données et semble les forcer à prendre la forme désirée. Cela peut être problématique si vous voulez, par exemple, prendre des moyennes de colonnes.

Voici une illustration de ce que je veux dire. Supposons que nous ayons le tableau suivant

>>> arr.shape
(2, 3, 4)
>>> arr 
array([[[1, 2, 3, 4],
        [1, 2, 3, 4],
        [1, 2, 3, 4]],

       [[7, 7, 7, 7],
        [7, 7, 7, 7],
        [7, 7, 7, 7]]])

Nous appliquons les deux méthodes pour obtenir un tableau de forme (3,8)

>>> arr.reshape((3,8)).shape
(3, 8)
>>> np.hstack(arr).shape 
(3, 8)

Cependant, si nous examinons la manière dont ils ont été remodelés dans chaque cas, la hstack nous permettrait de prendre des sommes de colonnes que nous aurions également pu calculer à partir du tableau original. Avec reshape, ce n'est pas possible.

>>> arr.reshape((3,8))
array([[1, 2, 3, 4, 1, 2, 3, 4],
       [1, 2, 3, 4, 7, 7, 7, 7],
       [7, 7, 7, 7, 7, 7, 7, 7]])
>>> np.hstack(arr)
array([[1, 2, 3, 4, 7, 7, 7, 7],
       [1, 2, 3, 4, 7, 7, 7, 7],
       [1, 2, 3, 4, 7, 7, 7, 7]])

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X