So reduzieren Sie nur einige Dimensionen eines Numpy-Arrays


127

Gibt es eine schnelle Möglichkeit, nur einige der ersten Dimensionen in einem Numpy-Array zu "unterflachen" oder nur zu glätten?

Bei einem numpy-Array von (50,100,25)Dimensionen wären die resultierenden Dimensionen beispielsweise(5000,25)



Sie benötigen einen Auffrischungskurs zum Schneiden von Numpy-Ndarray-Arrays. Auch bekannt als mehrdimensionale Array - Indizierung finden Sie unter : docs.scipy.org/doc/numpy-1.13.0/reference/arrays.indexing.html Array slice Ihre ndarray eckige Klammern verwenden, und verwenden Sie das Komma als Trennzeichen zu trennen , wie viel von jedem Dimension, die Sie wollen. Es sieht ungefähr so ​​aus (nicht genau): your_array[50:100, 7, :]Dadurch wird das 3D-Objekt auf 2d abgeflacht, wobei nur Slice Nummer 7 für die 2. Dimension verwendet wird.
Eric Leschinski

Antworten:


129

Schauen Sie sich numpy.reshape an .

>>> 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)

81

Eine leichte Verallgemeinerung von Alexanders Antwort - np.reshape kann -1 als Argument nehmen, was "Gesamtgröße des Arrays geteilt durch das Produkt aller anderen aufgelisteten Dimensionen" bedeutet:

zB um alle bis auf die letzte Dimension zu glätten:

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

33

Eine leichte Verallgemeinerung der Antwort von Peter: Sie können einen Bereich über der Form des ursprünglichen Arrays angeben, wenn Sie über dreidimensionale Arrays hinausgehen möchten.

zB um alle bis auf die letzten beiden Dimensionen zu glätten :

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

EDIT: Eine leichte Verallgemeinerung meiner früheren Antwort - Sie können natürlich auch einen Bereich am Anfang der Umformung angeben:

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)

2
Es ist schon mehr als zwei Jahre her ... Wir brauchen noch eine leichte Verallgemeinerung! ;)
Lith

1

Ein alternativer Ansatz ist die Verwendung numpy.resize()wie folgt :

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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.