首页 > 解决方案 > Numpy 通过索引列表调用数组值

问题描述

我有一个二维值数组,我想通过两个索引 x,y 列表来调用它。以前可以完美运行,现在不知道为什么不行,可能是python版本,不确定。

x = np.squeeze(np.where(data['info'][:,2]==cdp)[0])
y = np.squeeze(np.where((data['Time']>=ub) & (data['Time']<=lb))[0])

s = data['gather'][x,y]

错误:

IndexError: shape mismatch: indexing arrays could not be broadcast together with shapes (36,) (45,) 

我不知道是什么问题。当我分两个阶段进行时,它会起作用。

s = data['gather'][:,y]; s = s[x,:]

但是,我不能这样做,我需要一次性完成

标签: pythonnumpy

解决方案


In [92]: data = np.arange(12).reshape(3,4)                                                                           
In [93]: x,y = np.arange(3), np.arange(4)                                                                            
In [94]: data[x,y]                                                                                                   
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-94-8bd18da6c0ef> in <module>
----> 1 data[x,y]

IndexError: shape mismatch: indexing arrays could not be broadcast together with shapes (3,) (4,) 

When you provide 2 or more arrays as indices, numpy broadcasts them against each other. Understanding broadcasting is important.

In MATLAB providing two indexing arrays (actually 2d matrices) fetches a block. In numpy, to arrays, if they match in shape, fetch elements, e.g. a diagonal:

In [99]: data[x,x]                                                                                                   
Out[99]: array([ 0,  5, 10])

The MATLAB equivalent requires an extra function, 'indices to sub' or some such name.

Two stage indexing:

In [95]: data[:,y][x,:]                                                                                              
Out[95]: 
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])

ix_ is a handy tool for constructing indices for block access:

In [96]: data[np.ix_(x,y)]                                                                                           
Out[96]: 
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])

Notice what it produces:

In [97]: np.ix_(x,y)                                                                                                 
Out[97]: 
(array([[0],
        [1],
        [2]]), array([[0, 1, 2, 3]]))

that's the same as doing:

In [98]: data[x[:,None], y]                                                                                          
Out[98]: 
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])

x[:,None] is (3,1), y is (4,); they broadcast to produce a (3,4) selection.


推荐阅读