Làm cách nào để lấy các phần tử từ ma trận 3D bằng cách sử dụng các chỉ số cụ thể trong numpy?
- Tôi có ma trận 3D, trong ví dụ dưới đây là ma trận (5, 4, 2):
data_matrix - Tôi có một mảng chỉ mục khác của hình dạng (5, 4) trong đó mỗi hàng của mảng đại diện cho vị trí phần tử:
indx_array
Tôi không biết làm thế nào tôi có thể lấy được required_output. Tôi đang cố gắng sắp xếp (1,2) phần tử của mỗi hàng dựa trênindx_array
Tôi không muốn sử dụng cho các vòng lặp!
data_matrix = np.array([
[[0, 1], [2, 3], [4, 5], [6, 7]],
[[8, 9], [10, 11], [12, 13], [14, 15]],
[[16, 17], [18, 19], [20, 21], [22, 23]],
[[24, 25], [26, 27], [28, 29], [30, 31]],
[[32, 33], [34, 35], [36, 37], [38, 39]]
])
indx_array = np.array([[3,2,1,0], [0,1,2,3], [1,0,3,2], [0,3,1,2], [1,2,3,0]])
# I want following result:
required_output = [
[[6, 7], [4, 5], [2, 3], [0, 1]]
[[8, 9], [10, 11], [12, 13], [14, 15]]
[[18, 19], [16, 17], [22, 23], [20, 21]]
[[24, 25], [30, 31], [26, 27], [28, 29]]
[[34, 35], [36, 37], [38, 39], [32, 33]]
]
EDIT: Đã cập nhật indx_arrayđể minh họa tốt hơn tình hình.
Trả lời
- Numpy: Lập chỉ mục
- Numpy: Lập chỉ mục các mảng đa chiều
In [637]: data_matrix.shape
Out[637]: (5, 4, 2)
In [638]: indx_array.shape
Out[638]: (5, 4)
Bạn cần lập chỉ mục nâng cao trên 2 thứ nguyên đầu tiên. Mảng thứ nguyên đầu tiên cần phát sóng với thứ hai (5,4). Để làm điều đó, tôi thực hiện (5,1) arange:
In [639]: data_matrix[np.arange(5)[:,None], indx_array]
Out[639]:
array([[[ 6, 7],
[ 4, 5],
[ 2, 3],
[ 0, 1]],
[[ 8, 9],
[10, 11],
[12, 13],
[14, 15]],
[[18, 19],
[16, 17],
[22, 23],
[20, 21]],
[[24, 25],
[30, 31],
[26, 27],
[28, 29]],
[[34, 35],
[36, 37],
[38, 39],
[32, 33]]])
Đối chiếu chỉ mục (5,1) của tôi với chỉ mục được chấp nhận _x(là (5,4) được làm nghiêng):
In [640]: np.arange(5)[:,None]
Out[640]:
array([[0],
[1],
[2],
[3],
[4]])
In [641]: _x = np.repeat(np.arange(indx_array.shape[0]),indx_array.shape[1])
In [643]: _x
Out[643]: array([0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4])
Với việc phát sóng _xkhông cần lặp lại, (5,4); (5,1) là đủ.
Việc phát sóng thực hiện một sự lặp lại ảo. Điều này có thể được minh họa bằng broadcast_tohàm:
In [648]: np.broadcast_to(np.arange(5)[:,None],(5,4))
Out[648]:
array([[0, 0, 0, 0],
[1, 1, 1, 1],
[2, 2, 2, 2],
[3, 3, 3, 3],
[4, 4, 4, 4]])
In [649]: _.strides
Out[649]: (8, 0)
Đó là 0những bước đi lặp lại mà không cần tạo bản sao. as_stridedlà stride_trickschức năng hữu ích nhất , đặc biệt khi làm những việc như di chuyển cửa sổ. Thông thường, chúng tôi chỉ để phát sóng tự động làm công việc mà không cần lo lắng quá nhiều về cách thức.
Có thể được thực hiện với một chút bàn giao của mảng chỉ mục.
import numpy as np
_x = np.repeat(np.arange(indx_array.shape[0]),indx_array.shape[1])
_y = indx_array.ravel()
output = data_matrix[_x, _y].reshape(data_matrix.shape)
kết quả là mảng numpy dự kiến
array([[[ 6, 7],
[ 4, 5],
[ 2, 3],
[ 0, 1]],
[[ 8, 9],
[10, 11],
[12, 13],
[14, 15]],
[[18, 19],
[16, 17],
[22, 23],
[20, 21]],
[[24, 25],
[30, 31],
[26, 27],
[28, 29]],
[[34, 35],
[36, 37],
[38, 39],
[32, 33]]])