Jak spłaszczyć tylko niektóre wymiary tablicy numpy

129

Czy istnieje szybki sposób na „spłaszczenie częściowe” lub spłaszczenie tylko niektórych pierwszych wymiarów w tablicy numpy?

Na przykład, mając numeryczną tablicę wymiarów (50,100,25), wynikowymi wymiarami będą(5000,25)

Ciekawy
źródło
Potrzebujesz odświeżającego kursu na temat dzielenia tablic numpy ndarray. Znane również jako wielowymiarowe indeksowanie tablic, zobacz: docs.scipy.org/doc/numpy-1.13.0/reference/arrays.indexing.html Wyciąć tablicę ndarray za pomocą nawiasów kwadratowych i użyć separatora przecinka, aby oddzielić, ile z nich wymiar, który chcesz. Będzie to wyglądało mniej więcej tak (nie do końca): your_array[50:100, 7, :]co spłaszcza obiekt 3D do 2d, używając tylko wycinka numer 7 dla drugiego wymiaru.
Eric Leschinski

Odpowiedzi:

129

Spójrz na 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)
Alexander
źródło
82

Nieznaczne uogólnienie odpowiedzi Aleksandra - np.reshape może przyjąć -1 jako argument, co oznacza "całkowity rozmiar tablicy podzielony przez iloczyn wszystkich innych wymienionych wymiarów":

np. aby spłaszczyć wszystkie wymiary oprócz ostatniego:

>>> arr = numpy.zeros((50,100,25))
>>> new_arr = arr.reshape(-1, arr.shape[-1])
>>> new_arr.shape
# (5000, 25)
Piotr
źródło
33

Nieznaczne uogólnienie odpowiedzi Petera - jeśli chcesz wyjść poza tablice trójwymiarowe, możesz określić zakres w stosunku do kształtu oryginalnej tablicy.

np. spłaszczenie wszystkich wymiarów oprócz dwóch ostatnich :

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

EDYCJA: Niewielkie uogólnienie mojej wcześniejszej odpowiedzi - możesz oczywiście określić również zakres na początku zmiany kształtu:

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)
KeithWM
źródło
2
Minęły już ponad dwa lata ... Potrzebujemy jeszcze jednego drobnego uogólnienia! ;)
Lith
1

Alternatywnym podejściem jest użycie numpy.resize()jak w:

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
kmario23
źródło