Python 在numpy中按一个数组索引另一个数组

Python 在numpy中按一个数组索引另一个数组,python,numpy,Python,Numpy,假设我有一个矩阵a,其中包含一些任意值: array([[ 2, 4, 5, 3], [ 1, 6, 8, 9], [ 8, 7, 0, 2]]) 以及矩阵B,其中包含a中元素的索引: array([[0, 0, 1, 2], [0, 3, 2, 1], [3, 2, 1, 0]]) 如何从B指向的A中选择值,即: A[B] = [[2, 2, 4, 5], [1, 9, 8, 6], [2, 0, 7,

假设我有一个矩阵a,其中包含一些任意值:

array([[ 2, 4, 5, 3],
       [ 1, 6, 8, 9],
       [ 8, 7, 0, 2]])
以及矩阵B,其中包含a中元素的索引:

array([[0, 0, 1, 2],
       [0, 3, 2, 1],
       [3, 2, 1, 0]])
如何从B指向的A中选择值,即:

A[B] = [[2, 2, 4, 5],
        [1, 9, 8, 6],
        [2, 0, 7, 8]]

编辑:
np.take_沿_轴
是自
numpy
1.15以来实现的该用例的内置函数。有关如何使用它,请参见下面的@hpaulj


你可以用-

还可以使用
线性索引
-

m,n = A.shape
out = np.take(A,B + n*np.arange(m)[:,None])
样本运行-

In [40]: A
Out[40]: 
array([[2, 4, 5, 3],
       [1, 6, 8, 9],
       [8, 7, 0, 2]])

In [41]: B
Out[41]: 
array([[0, 0, 1, 2],
       [0, 3, 2, 1],
       [3, 2, 1, 0]])

In [42]: A[np.arange(A.shape[0])[:,None],B]
Out[42]: 
array([[2, 2, 4, 5],
       [1, 9, 8, 6],
       [2, 0, 7, 8]])

In [43]: m,n = A.shape

In [44]: np.take(A,B + n*np.arange(m)[:,None])
Out[44]: 
array([[2, 2, 4, 5],
       [1, 9, 8, 6],
       [2, 0, 7, 8]])

以下是使用
for
循环的解决方案:

outlist = []
for i in range(len(B)):
    lst = []    
    for j in range(len(B[i])):
        lst.append(A[i][B[i][j]])
    outlist.append(lst)
outarray = np.asarray(outlist)
print(outarray)
以上内容也可以用更简洁的列表理解形式书写:

outlist = [ [A[i][B[i][j]] for j in range(len(B[i]))]
                for i in range(len(B))  ]
outarray = np.asarray(outlist)
print(outarray)
输出:

[[2 2 4 5]
 [1 9 8 6]
 [2 0 7 8]]

较新的版本添加了一个执行此任务的
沿轴取\u
功能:

A = np.array([[ 2, 4, 5, 3], 
              [ 1, 6, 8, 9], 
              [ 8, 7, 0, 2]])  
                                          
B = np.array([[0, 0, 1, 2], 
              [0, 3, 2, 1], 
              [3, 2, 1, 0]])     
                                        
np.take_along_axis(A, B, 1)  
                                       
Out[]: 
array([[2, 2, 4, 5],
       [1, 9, 8, 6],
       [2, 0, 7, 8]])

还有一个
沿_轴放置

我知道这是一个老问题,但使用索引的另一种方法是:

A[np.indices(B.shape)[0], B]
输出:

[[2 2 4 5]
 [1 9 8 6]
 [2 0 7 8]]

我不明白这些是怎么工作的。。。您可以添加一些解释吗?@JasonS基本上使用沿第一个轴的范围数组为
B
中的每个元素沿该轴选择一个范围数组。提供的链接应提供所需的所有详细信息。嗯。。。好吧,那很好,但是我看了高级索引链接,它对我来说没有意义。我需要将您的示例扩展到一个仅应用最后一个索引的N维数组,我不确定如何执行。问题的提出者正在寻找一种使用简单切片而不是循环的解决方案。切片速度比循环快得难以置信。非常优雅的方法!
[[2 2 4 5]
 [1 9 8 6]
 [2 0 7 8]]