Cara meratakan hanya beberapa dimensi dari array numpy

128

Apakah ada cara cepat untuk "meratakan" atau meratakan hanya beberapa dimensi pertama dalam larik numpy?

Misalnya, dalam larik dimensi yang numpy (50,100,25), dimensi yang dihasilkan adalah(5000,25)

Ingin tahu
sumber
Anda memerlukan kursus penyegaran tentang pengirisan array ndarray numpy. Juga dikenal sebagai pengindeksan array multi-dimensi, lihat: docs.scipy.org/doc/numpy-1.13.0/reference/arrays.indexing.html Array mengiris ndarray Anda menggunakan tanda kurung siku, dan menggunakan pemisah koma untuk memisahkan berapa banyak dari masing-masing dimensi yang Anda inginkan. Ini akan terlihat seperti (tidak persis) ini: your_array[50:100, 7, :]yang meratakan objek 3d menjadi 2d, hanya menggunakan potongan nomor 7 untuk dimensi ke-2.
Eric Leschinski

Jawaban:

129

Lihatlah 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
sumber
81

Sedikit generalisasi untuk jawaban Alexander - np.reshape dapat menggunakan -1 sebagai argumen, yang berarti "ukuran larik total dibagi dengan produk dari semua dimensi lain yang terdaftar":

misalnya untuk meratakan semua kecuali dimensi terakhir:

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

Sedikit generalisasi untuk jawaban Peter - Anda dapat menentukan rentang di atas bentuk larik asli jika Anda ingin melampaui larik tiga dimensi.

misalnya untuk meratakan semua kecuali dua dimensi terakhir :

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

EDIT: Sedikit generalisasi untuk jawaban saya sebelumnya - Anda dapat, tentu saja, juga menentukan rentang di awal pembentukan ulang juga:

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
sumber
2
Sudah lebih dari dua tahun ... Kita perlu sedikit generalisasi! ;)
Lith
1

Pendekatan alternatif adalah dengan menggunakan numpy.resize()seperti pada:

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
sumber