Ini adalah bagaimana numpy menggunakan pengindeksan tingkat lanjut untuk menyiarkan bentuk array. Saat Anda melewati a 0
untuk indeks pertama, dan y
untuk indeks terakhir, numpy akan menyiarkan 0
bentuk yang sama dengan y
. Kesetaraan berikut ini berlaku: x[0,:,:,y] == x[(0, 0, 0),:,:,y]
. di sini adalah sebuah contoh
import numpy as np
x = np.arange(120).reshape(2,3,4,5)
y = np.array([0,2,4])
np.equal(x[0,:,:,y], x[(0, 0, 0),:,:,y]).all()
# returns:
True
Sekarang, karena Anda secara efektif mengirimkan dua set indeks, Anda menggunakan API pengindeksan lanjutan untuk membentuk (dalam hal ini) pasangan indeks.
x[(0, 0, 0),:,:,y])
# equivalent to
[
x[0,:,:,y[0]],
x[0,:,:,y[1]],
x[0,:,:,y[2]]
]
# equivalent to
rows = np.array([0, 0, 0])
cols = y
x[rows,:,:,cols]
# equivalent to
[
x[r,:,:,c] for r, c in zip(rows, columns)
]
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 = np.arange(120).reshape(2,3,4,5)
y = np.array([0,2,4])
# x looks like:
array([[[[ 0, 1, 2, 3, 4], -+ =+
[ 5, 6, 7, 8, 9], Sheet1 |
[ 10, 11, 12, 13, 14], | |
[ 15, 16, 17, 18, 19]], -+ |
Workbook1
[[ 20, 21, 22, 23, 24], -+ |
[ 25, 26, 27, 28, 29], Sheet2 |
[ 30, 31, 32, 33, 34], | |
[ 35, 36, 37, 38, 39]], -+ |
|
[[ 40, 41, 42, 43, 44], -+ |
[ 45, 46, 47, 48, 49], Sheet3 |
[ 50, 51, 52, 53, 54], | |
[ 55, 56, 57, 58, 59]]], -+ =+
[[[ 60, 61, 62, 63, 64],
[ 65, 66, 67, 68, 69],
[ 70, 71, 72, 73, 74],
[ 75, 76, 77, 78, 79]],
[[ 80, 81, 82, 83, 84],
[ 85, 86, 87, 88, 89],
[ 90, 91, 92, 93, 94],
[ 95, 96, 97, 98, 99]],
[[100, 101, 102, 103, 104],
[105, 106, 107, 108, 109],
[110, 111, 112, 113, 114],
[115, 116, 117, 118, 119]]]])
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."
x[0,:,:,y[0]]
# returns:
array([[ 0, 5, 10, 15],
[20, 25, 30, 35],
[40, 45, 50, 55]])
# this is in the same as the first element in:
x[(0,0,0),:,:,y]
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 nilai y
th / kolom. Ok, sekarang lakukan untuk setiap nilai y
"
x[(0,0,0),:,:,y]
# returns:
array([[[ 0, 5, 10, 15],
[20, 25, 30, 35],
[40, 45, 50, 55]],
[[ 2, 7, 12, 17],
[22, 27, 32, 37],
[42, 47, 52, 57]],
[[ 4, 9, 14, 19],
[24, 29, 34, 39],
[44, 49, 54, 59]]])
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 dengannya y.shape
. Yaitu, dimensi terakhir dari indeks pertama harus 3 atau 1.
ix = np.array([[0], [1]])
x[ix,:,:,y].shape
# each row of ix is broadcast to length 3:
(2, 3, 3, 4)
ix = np.array([[0,0,0], [1,1,1]])
x[ix,:,:,y].shape
# this is identical to above:
(2, 3, 3, 4)
ix = np.array([[0], [1], [0], [1], [0]])
x[ix,:,:,y].shape
# ix is broadcast so each row of ix has 3 columns, the length of y
(5, 3, 3, 4)
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]
:
x[0][:,:,y].shape
# returns
(2, 50, 3)
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,:,:]
atau x[0,:,:,1:-1]
.
np.shares_memory(x, x[0])
# returns:
True
np.shares_memory(x, x[:,:,:,y])
# returns:
False
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:
x[0,:,:,0:21:10].shape
# returns:
(2, 50, 3)
np.shares_memory(x, x[0,:,:,0:21:10])
# returns:
True
# actually assigns to the original array
x[0,:,:,0:21:10] = 100
Di sini kita menggunakan irisan 0:21:10
untuk mengambil setiap indeks yang akan masuk range(0,21,10)
. Kita harus menggunakan 21
dan bukan 20
karena stop-point dikecualikan dari slice, sama seperti dalam range
fungsi.
Jadi pada dasarnya, jika Anda bisa membuat slice yang sesuai dengan kriteria berlangganan Anda, Anda bisa melakukan penugasan.