Saya memiliki variabel, x, yang berbentuk (2,2,50,100).
Saya juga memiliki array, y, yang sama dengan np.array ([0,10,20]). Suatu hal yang aneh terjadi ketika saya mengindeks x [0,:,:, y].
x = np.full((2,2,50,100),np.nan)
y = np.array([0,10,20])
print(x.shape)
(2,2,50,100)
print(x[:,:,:,y].shape)
(2,2,50,3)
print(x[0,:,:,:].shape)
(2,50,100)
print(x[0,:,:,y].shape)
(3,2,50)
Mengapa output terakhir (3,2,50) dan tidak (2,50,3)?
Jawaban:
Ini adalah bagaimana numpy menggunakan pengindeksan tingkat lanjut untuk menyiarkan bentuk array. Saat Anda melewati a
0
untuk indeks pertama, dany
untuk indeks terakhir, numpy akan menyiarkan0
bentuk yang sama dengany
. Kesetaraan berikut ini berlaku:x[0,:,:,y] == x[(0, 0, 0),:,:,y]
. di sini adalah sebuah contohSekarang, karena Anda secara efektif mengirimkan dua set indeks, Anda menggunakan API pengindeksan lanjutan untuk membentuk (dalam hal ini) pasangan indeks.
Yang memiliki dimensi pertama yang sama dengan panjang
y
. Ini yang Anda lihat.Sebagai contoh, lihat sebuah array dengan 4 dimensi yang dijelaskan dalam potongan berikutnya:
x
memiliki bentuk sekuensial yang sangat mudah dipahami yang sekarang dapat kita gunakan untuk menunjukkan apa yang terjadi ...Dimensi pertama seperti memiliki 2 Buku Kerja Excel, dimensi kedua seperti memiliki 3 lembar di setiap buku kerja, dimensi ketiga seperti memiliki 4 baris per lembar, dan dimensi terakhir adalah 5 nilai untuk setiap baris (atau kolom per lembar).
Melihat seperti ini, meminta
x[0,:,:,0]
, adalah pepatah: "di buku kerja pertama, untuk setiap lembar, untuk setiap baris, beri saya nilai / kolom pertama."Tetapi sekarang dengan pengindeksan tingkat lanjut, kita dapat menganggapnya
x[(0,0,0),:,:,y]
sebagai "di buku kerja pertama, untuk setiap lembar, untuk setiap baris, beri saya nilaiy
th / kolom. Ok, sekarang lakukan untuk setiap nilaiy
"Di mana menjadi gila adalah bahwa numpy akan disiarkan untuk mencocokkan dimensi luar array indeks. Jadi jika Anda ingin melakukan operasi yang sama seperti di atas, tetapi untuk KEDUA "buku kerja Excel", Anda tidak perlu mengulang dan menyatukan. Anda bisa meneruskan array ke dimensi pertama, tetapi itu HARUS memiliki bentuk yang kompatibel.
Melewati bilangan bulat disiarkan ke
y.shape == (3,)
. Jika Anda ingin melewatkan array sebagai indeks pertama, hanya dimensi terakhir dari array yang harus kompatibel dengannyay.shape
. Yaitu, dimensi terakhir dari indeks pertama harus 3 atau 1.Temukan penjelasan singkat dalam dokumen: https://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#combining-advanced-and-basic-indexing
Edit:
Dari pertanyaan awal, untuk mendapatkan satu-langganan berlangganan yang Anda inginkan, Anda dapat menggunakan
x[0][:,:,y]
:Namun, jika Anda mencoba untuk menetapkan untuk berlangganan tersebut, Anda harus sangat berhati-hati bahwa Anda sedang melihat tampilan memori bersama dari array asli. Kalau tidak, tugas tidak akan ke array asli, tetapi salinan.
Memori bersama hanya terjadi ketika Anda menggunakan integer atau slice untuk subset array Anda, yaitu
x[:,0:3,:,:]
ataux[0,:,:,1:-1]
.Baik dalam pertanyaan awal Anda maupun contoh saya
y
bukanlah int atau slice, maka akan selalu berakhir dengan menetapkan salinan asli.TAPI! Karena larik Anda untuk
y
dapat diekspresikan sebagai slice, Anda BISA benar-benar mendapatkan tampilan larik array Anda melalui:Di sini kita menggunakan irisan
0:21:10
untuk mengambil setiap indeks yang akan masukrange(0,21,10)
. Kita harus menggunakan21
dan bukan20
karena stop-point dikecualikan dari slice, sama seperti dalamrange
fungsi.Jadi pada dasarnya, jika Anda bisa membuat slice yang sesuai dengan kriteria berlangganan Anda, Anda bisa melakukan penugasan.
sumber
Ini disebut
combining advanced and basic indexing
. Dalamcombining advanced and basic indexing
, numpy melakukan pengindeksan di pengindeksan lanjutan pertama dan subruang / menggabungkan hasilnya ke dimensi pengindeksan dasar.Contoh dari dokumen:
jadi, aktif
x[0,:,:,y]
,0
dany
sedang maju pengindeksan. Mereka disiarkan bersama untuk menghasilkan dimensi(3,)
.Ini berlaku
(3,)
untuk awal dimensi 2 dan 3 untuk membuat(3, 2, 50)
Untuk melihat bahwa 1 dan dimensi terakhir benar-benar penyiaran bersama-sama, Anda dapat mencoba perubahan
0
untuk[0,1]
melihat kesalahan penyiaransumber