我正在寻找索引策略如何从原始数组(左侧)中选择子数组(右侧),然后用子代替原始数组阵列(底)。有一些索引可以为每行选择 ,例如对于第一行,它们是[1,3,0],最后一行是[4,6,2]。 下图中的完整选择矩阵如下所示:
[[1,3,0],
[2,3,2],
[4,0,6],
[1,4,0],
[4,6,2]]
到目前为止,我只能循环遍历原始数组的行并替换列索引处的值。 是否有没有循环的解决方案?
+--------------------------------------+
| |
| +-----------------------+ |
| | | |
| +----------------------------+ | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
+ + + v v v
array([[ 0, 1, 2, 3, 4, 5, 6], 1, 3, 0,
[ 7, 8, 9, 10, 11, 12, 13], 9,10,9,
!14, 15, 16, 17,!18, 19,!20], 18,14,20,
[21, 22, 23, 24, 25, 26, 27], 22,25,21,
[28, 29, 30, 31, 32, 33, 34]]) 32,34,30
+ + + ^ ^ ^
| | | | | |
| +----------------+ | |
| | | |
| +-----------+ |
| |
+-------------------------------+
最终数组是原始数组,替换了子数组中的最后一个索引(从原始数组中选择。
+------------+
array([[ 0, 1, 2, 3,| 1, 3, 0],|
[ 7, 8, 9, 10,| 9, 10, 9],|
[14, 15, 16, 17,|18, 14, 20],|
[21, 22, 23, 24,|22, 25, 21],|
[28, 29, 30, 31,|32, 34, 30]]|
+------------+
循环解决方案:
selection = np.array([[1,3,0],
[2,3,2],
[4,0,6],
[1,4,0],
[4,6,2]])
y = np.arange(35).reshape(5,7)
s = y.shape[1] - selection.shape[1]
e = y.shape[1]
for i in range(0, y.shape[0]):
y[i, s:e] = y[i, selection[i]]
>>> y
array([[ 0, 1, 2, 3, 1, 3, 0],
[ 7, 8, 9, 10, 9, 10, 9],
[14, 15, 16, 17, 18, 14, 20],
[21, 22, 23, 24, 22, 25, 21],
[28, 29, 30, 31, 32, 34, 30]])
答案 0 :(得分:2)
您可以通过创建行的索引来实现:
import numpy as np
a = 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]])
idx = np.array([[1,3,0],
[2,3,2],
[4,0,6],
[1,4,0],
[4,6,2]])
rows = np.tile(np.arange(len(idx)), [idx.shape[1], 1]).T
# This array looks like this:
# [[0, 0, 0],
# [1, 1, 1],
# [2, 2, 2],
# [3, 3, 3],
# [4, 4, 4]]
a[:, -idx.shape[1]:] = a[rows, idx]
print(a)
输出:
array([[ 0, 1, 2, 3, 1, 3, 0],
[ 7, 8, 9, 10, 9, 10, 9],
[14, 15, 16, 17, 18, 14, 20],
[21, 22, 23, 24, 22, 25, 21],
[28, 29, 30, 31, 32, 34, 30]])
答案 1 :(得分:2)
使用broaodcasting和高级索引:
>>> y[:, 4:] = y[np.arange(5)[:, None], selection]
>>> y
array([[ 0, 1, 2, 3, 1, 3, 0],
[ 7, 8, 9, 10, 9, 10, 9],
[14, 15, 16, 17, 18, 14, 20],
[21, 22, 23, 24, 22, 25, 21],
[28, 29, 30, 31, 32, 34, 30]])