Đây là cách numpy sử dụng lập chỉ mục nâng cao để phát hình dạng mảng. Khi bạn vượt qua a 0
cho chỉ mục đầu tiên và y
cho chỉ mục cuối cùng, numpy sẽ phát sóng 0
thành hình dạng giống như y
. Tương đương sau giữ : x[0,:,:,y] == x[(0, 0, 0),:,:,y]
. đây là một ví dụ
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
Bây giờ, vì bạn thực sự chuyển qua hai bộ chỉ mục, nên bạn đang sử dụng API lập chỉ mục nâng cao để tạo thành các cặp chỉ mục (trong trường hợp này).
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)
]
Mà có một chiều đầu tiên giống như chiều dài của y
. Đây là những gì bạn đang thấy.
Ví dụ, nhìn vào một mảng có 4 kích thước được mô tả trong đoạn tiếp theo:
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
có một dạng tuần tự thực sự dễ hiểu mà bây giờ chúng ta có thể sử dụng để hiển thị những gì đang xảy ra ...
Kích thước thứ nhất giống như có 2 Sổ làm việc Excel, kích thước thứ hai giống như có 3 trang tính trong mỗi sổ làm việc, kích thước thứ ba giống như có 4 hàng trên mỗi trang tính và kích thước cuối cùng là 5 giá trị cho mỗi hàng (hoặc cột trên mỗi trang tính).
Nhìn vào nó theo cách này, yêu cầu x[0,:,:,0]
, là câu nói: "trong sổ làm việc đầu tiên, cho mỗi tờ, cho mỗi hàng, hãy cho tôi giá trị / cột đầu tiên."
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]
Nhưng bây giờ với lập chỉ mục nâng cao, chúng ta có thể nghĩ x[(0,0,0),:,:,y]
là "trong sổ làm việc đầu tiên, cho mỗi trang tính, cho mỗi hàng, hãy đưa cho tôi y
giá trị / cột thứ. Ok, bây giờ hãy làm điều đó cho từng giá trị của 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]]])
Điều khiến nó trở nên điên rồ là numpy sẽ phát sóng để phù hợp với kích thước bên ngoài của mảng chỉ mục. Vì vậy, nếu bạn muốn thực hiện thao tác tương tự như trên, nhưng đối với CẢ "sổ làm việc Excel", bạn không phải lặp và nối. Bạn chỉ có thể truyền một mảng cho kích thước đầu tiên, nhưng nó PHẢI có hình dạng tương thích.
Truyền một số nguyên được phát đến y.shape == (3,)
. Nếu bạn muốn vượt qua một mảng làm chỉ mục đầu tiên, chỉ có thứ nguyên cuối cùng của mảng phải tương thích với y.shape
. Tức là kích thước cuối cùng của chỉ mục đầu tiên phải là 3 hoặc 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)
Tìm thấy một lời giải thích ngắn trong các tài liệu: https://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#combining-advified-and-basic-indexing
Biên tập:
Từ câu hỏi ban đầu, để có được một lớp lót về mức độ mong muốn của bạn, bạn có thể sử dụng x[0][:,:,y]
:
x[0][:,:,y].shape
# returns
(2, 50, 3)
Tuy nhiên, nếu bạn đang cố gắng gán cho các phần tử đó, bạn phải rất cẩn thận rằng bạn đang xem chế độ xem bộ nhớ được chia sẻ của mảng ban đầu. Nếu không, bài tập sẽ không thuộc về mảng ban đầu, mà là một bản sao.
Bộ nhớ dùng chung chỉ xảy ra khi bạn đang sử dụng một số nguyên hoặc lát để tập hợp mảng của bạn, tức là x[:,0:3,:,:]
hoặc x[0,:,:,1:-1]
.
np.shares_memory(x, x[0])
# returns:
True
np.shares_memory(x, x[:,:,:,y])
# returns:
False
Trong cả câu hỏi ban đầu của bạn và ví dụ của tôi y
không phải là int hay lát, vì vậy sẽ luôn luôn gán cho một bản sao của bản gốc.
NHƯNG! Bởi vì mảng của bạn cho y
có thể được diễn tả như một lát, bạn CÓ THỂ thực sự có được một cái nhìn chuyển nhượng của mảng của bạn thông qua:
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
Ở đây chúng tôi sử dụng lát cắt 0:21:10
để lấy mọi chỉ số sẽ có trong đó range(0,21,10)
. Chúng ta phải sử dụng 21
và không phải 20
vì điểm dừng được loại trừ khỏi lát cắt, giống như trong range
hàm.
Vì vậy, về cơ bản, nếu bạn có thể xây dựng một lát cắt phù hợp với tiêu chí của bạn, bạn có thể thực hiện chuyển nhượng.