Gunakan tampilan dan dapatkan runtime gratis! Perluas n-dim
larik generik ken+1-dim
Diperkenalkan di NumPy1.10.0
, kita dapat memanfaatkan numpy.broadcast_to
untuk menghasilkan 3D
tampilan ke dalam 2D
larik input. Manfaatnya tidak akan ada overhead memori tambahan dan runtime yang hampir bebas. Ini akan menjadi penting dalam kasus di mana array besar dan kami baik-baik saja untuk bekerja dengan view. Juga, ini akan bekerja dengan n-dim
kasus umum .
Saya akan menggunakan kata tersebut stack
sebagai pengganti copy
, karena pembaca mungkin bingung dengan menyalin array yang membuat salinan memori.
Tumpuk di sepanjang sumbu pertama
Jika kita ingin menumpuk input di arr
sepanjang sumbu pertama, solusi dengan np.broadcast_to
membuat 3D
tampilan adalah -
np.broadcast_to(arr,(3,)+arr.shape) # N = 3 here
Tumpuk di sepanjang sumbu ketiga / terakhir
Untuk menumpuk input di arr
sepanjang sumbu ketiga, solusi untuk membuat 3D
tampilan adalah -
np.broadcast_to(arr[...,None],arr.shape+(3,))
Jika kita benar-benar membutuhkan salinan memori, kita selalu dapat menambahkannya di .copy()
sana. Oleh karena itu, solusinya adalah -
np.broadcast_to(arr,(3,)+arr.shape).copy()
np.broadcast_to(arr[...,None],arr.shape+(3,)).copy()
Berikut cara kerja penumpukan untuk dua kasing, yang ditunjukkan dengan informasi bentuknya untuk contoh kasing -
# Create a sample input array of shape (4,5)
In [55]: arr = np.random.rand(4,5)
# Stack along first axis
In [56]: np.broadcast_to(arr,(3,)+arr.shape).shape
Out[56]: (3, 4, 5)
# Stack along third axis
In [57]: np.broadcast_to(arr[...,None],arr.shape+(3,)).shape
Out[57]: (4, 5, 3)
Solusi yang sama akan bekerja untuk memperluas n-dim
masukan untuk n+1-dim
melihat keluaran sepanjang sumbu pertama dan terakhir. Mari jelajahi beberapa casing redup yang lebih tinggi -
Kasus masukan 3D:
In [58]: arr = np.random.rand(4,5,6)
# Stack along first axis
In [59]: np.broadcast_to(arr,(3,)+arr.shape).shape
Out[59]: (3, 4, 5, 6)
# Stack along last axis
In [60]: np.broadcast_to(arr[...,None],arr.shape+(3,)).shape
Out[60]: (4, 5, 6, 3)
Kasus masukan 4D:
In [61]: arr = np.random.rand(4,5,6,7)
# Stack along first axis
In [62]: np.broadcast_to(arr,(3,)+arr.shape).shape
Out[62]: (3, 4, 5, 6, 7)
# Stack along last axis
In [63]: np.broadcast_to(arr[...,None],arr.shape+(3,)).shape
Out[63]: (4, 5, 6, 7, 3)
dan seterusnya.
Pengaturan waktu
Mari gunakan contoh 2D
kasus yang besar dan dapatkan pengaturan waktu dan verifikasi keluaran menjadi a view
.
# Sample input array
In [19]: arr = np.random.rand(1000,1000)
Mari kita buktikan bahwa solusi yang diusulkan memang sebuah pandangan. Kami akan menggunakan penumpukan di sepanjang sumbu pertama (hasilnya akan sangat mirip untuk penumpukan di sepanjang sumbu ketiga) -
In [22]: np.shares_memory(arr, np.broadcast_to(arr,(3,)+arr.shape))
Out[22]: True
Mari kita dapatkan pengaturan waktu untuk menunjukkan bahwa ini hampir gratis -
In [20]: %timeit np.broadcast_to(arr,(3,)+arr.shape)
100000 loops, best of 3: 3.56 µs per loop
In [21]: %timeit np.broadcast_to(arr,(3000,)+arr.shape)
100000 loops, best of 3: 3.51 µs per loop
Sebagai tampilan, meningkat N
dari 3
menjadi 3000
tidak mengubah apa pun pada pengaturan waktu dan keduanya dapat diabaikan pada unit pengaturan waktu. Karenanya, efisien baik dalam memori dan kinerja!
b[:,:,0]
,b[:,:,1]
danb[:,:,2]
. Setiap potongan dimensi ketiga adalah salinan dari larik 2D asli. Ini tidak begitu jelas hanya dengan melihatprint(b)
.