0

I have a 2D array of values, and I want to call it by two list of indices x,y. It used to work perfect before, I don't know why it's not working now, maybe python version, not sure.

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]

Error:

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

I don't what is the problem. It works when I do it in two stages.

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

But, I can't do this, I need to do at one run

6
  • 1
    Can you simply try data['gather'][:,y][x,:] ? Commented Mar 19, 2020 at 10:44
  • You can't index an array with 2 arrays that don't broadcast together. Reread the advanced indexing section of the docs. You never could. Commented Mar 19, 2020 at 10:47
  • MATLAB and numpy are different in how they handle indexing of blocks. x[[0,1,2], [0,1,2]] selects a diagonal, not a (3,3) block. Commented Mar 19, 2020 at 11:21
  • @NikP 's way should be correct. Commented Mar 19, 2020 at 12:59
  • What's data? Dictionary? dataframe? Commented Mar 19, 2020 at 15:17

1 Answer 1

1
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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.