15

我有两个矩阵,A并且B

A = array([[2., 13., 25., 1.], [ 18., 5., 1., 25.]])
B = array([[2, 1], [0, 3]])

我想用 的每一行来索引每一行AB产生切片:

array([[25., 13.], [18., 25.]])

也就是说,我本质上想要类似的东西:

array([A[i,b] for i,b in enumerate(B)])

有没有办法直接对它进行索引?我能做的最好的就是这个“flat-hack”:

A.flat[B + arange(0,A.size,A.shape[1])[:,None]]
4

2 回答 2

13

@Ophion 的回答很棒,值得称赞,但我想添加一些解释,并提供更直观的结构。

与其先旋转B然后再旋转结果,不如只旋转arange. 我认为这给出了最直观的解决方案,即使它需要更多字符:

A[((0,),(1,)), B]

或等效地

A[np.arange(2)[:, None], B]

这是有效的,因为这里真正发生的是,您正在制作一个i数组和一个j数组,每个数组的形状都与您想要的结果相同。

i = np.array([[0, 0],
              [1, 1]])
j = B

但你可以只使用

i = np.array([[0],
              [1]])

因为它将广播匹配B(这就是np.arange(2)[:,None]给出的)。

最后,为了使其更通用(不知道大小),您还可以2生成from witharangeiB

i = np.indices(B.shape)[0]

无论您如何构建ij您都可以这样称呼它

>>> A[i, j]
array([[ 25.,  13.],
       [ 18.,  25.]])
于 2013-11-04T20:10:13.410 回答
9

不漂亮但是:

A[np.arange(2),B.T].T
array([[ 25.,  13.],
       [ 18.,  25.]])
于 2013-11-04T19:54:10.760 回答