通过没有循环的2D索引数组索引2D numpy数组

时间:2022-04-10 21:40:34

I am looking for a vectorized way to index a numpy.array by numpy.array of indices.

我正在寻找一种矢量化的方法来索引numpy.array由numpy.array索引。

For example:

import numpy as np

a = np.array([[0,3,4],
              [5,6,0],
              [0,1,9]])

inds = np.array([[0,1],
                 [1,2],
                 [0,2]])

I want to build a new array, such that every row(i) in that array is a row(i) of array a, indexed by row of array inds(i). My desired output is:

我想构建一个新数组,这样该数组中的每一行(i)都是数组a的一行(i),由数组inds(i)的行索引。我想要的输出是:

array([[ 0.,  3.],   # a[0][:,[0,1]]
       [ 6.,  0.],   # a[1][:,[1,2]] 
       [ 0.,  9.]])  # a[2][:,[0,2]]

I can achieve this with a loop:

我可以用循环来实现这个目的:

def loop_way(my_array, my_indices):
    new_array = np.empty(my_indices.shape)
    for i in xrange(len(my_indices)):
        new_array[i, :] = my_array[i][:, my_indices[i]]
    return new_array 

But I am looking for a pure vectorized solution.

但我正在寻找一种纯粹的矢量化解决方案。

2 个解决方案

#1


5  

When using arrays of indices to index another array, the shape of each index array should match the shape of the output array. You want the column indices to match inds, and you want the row indices to match the row of the output, something like:

使用索引数组索引另一个数组时,每个索引数组的形状应与输出数组的形状匹配。您希望列索引与inds匹配,并且您希望行索引与输出的行匹配,例如:

array([[0, 0],
       [1, 1],
       [2, 2]])

You can just use a single column of the above, due to broadcasting, so you can use np.arange(3)[:,None] is the vertical arange because None inserts a new axis:

由于广播,您可以使用上面的单个列,因此您可以使用np.arange(3)[:,None]是垂直范围,因为None会插入新轴:

>>> np.arange(3)[:, None]
array([[0],
       [1],
       [2]])

Finally, together:

>>> a[np.arange(3)[:,None], inds]
array([[0, 3],   # a[0,[0,1]]
       [6, 0],   # a[1,[1,2]] 
       [0, 9]])  # a[2,[0,2]]

#2


2  

It’s possible, although somewhat non-obvious to do this as follows:

虽然有些不明显,但可能如下:

>>> a[np.arange(a.shape[0])[:, None], inds]
array([[0, 3],
       [6, 0],
       [0, 9]])

The index np.arange(a.shape[0]) simply indexes the rows to which the array of column indices inds applies. Appending [:, None] modifies the shape of this array such that its shape is (a.shape[0], 1), i.e. each row index is in a separate row of a 1-column-wide 2D array.

索引np.arange(a.shape [0])简单地索引列索引inds数组所应用的行。附加[:,None]修改此数组的形状,使其形状为(a.shape [0],1),即每个行索引位于1列宽的2D数组的单独行中。

The basic principle is that the number of dimensions in the index arrays must agree, and their shapes must also do so. See documentation for np.ix_ to get a feel for this.

基本原则是索引数组中的维数必须一致,它们的形状也必须这样。请参阅np.ix_的文档以了解这一点。

#1


5  

When using arrays of indices to index another array, the shape of each index array should match the shape of the output array. You want the column indices to match inds, and you want the row indices to match the row of the output, something like:

使用索引数组索引另一个数组时,每个索引数组的形状应与输出数组的形状匹配。您希望列索引与inds匹配,并且您希望行索引与输出的行匹配,例如:

array([[0, 0],
       [1, 1],
       [2, 2]])

You can just use a single column of the above, due to broadcasting, so you can use np.arange(3)[:,None] is the vertical arange because None inserts a new axis:

由于广播,您可以使用上面的单个列,因此您可以使用np.arange(3)[:,None]是垂直范围,因为None会插入新轴:

>>> np.arange(3)[:, None]
array([[0],
       [1],
       [2]])

Finally, together:

>>> a[np.arange(3)[:,None], inds]
array([[0, 3],   # a[0,[0,1]]
       [6, 0],   # a[1,[1,2]] 
       [0, 9]])  # a[2,[0,2]]

#2


2  

It’s possible, although somewhat non-obvious to do this as follows:

虽然有些不明显,但可能如下:

>>> a[np.arange(a.shape[0])[:, None], inds]
array([[0, 3],
       [6, 0],
       [0, 9]])

The index np.arange(a.shape[0]) simply indexes the rows to which the array of column indices inds applies. Appending [:, None] modifies the shape of this array such that its shape is (a.shape[0], 1), i.e. each row index is in a separate row of a 1-column-wide 2D array.

索引np.arange(a.shape [0])简单地索引列索引inds数组所应用的行。附加[:,None]修改此数组的形状,使其形状为(a.shape [0],1),即每个行索引位于1列宽的2D数组的单独行中。

The basic principle is that the number of dimensions in the index arrays must agree, and their shapes must also do so. See documentation for np.ix_ to get a feel for this.

基本原则是索引数组中的维数必须一致,它们的形状也必须这样。请参阅np.ix_的文档以了解这一点。