Numpy subrange assignment with extended mixed indexing

Original question

I am getting a very strange error message when I try to assign some elements to an array. I am using a combination of slice and index set. See the next simple example.

 import scipy as sp

 a = sp.zeros((3, 4, 5))
 b = sp.ones((4, 5))

 I = sp.array([0, 1, 3])

 b[:, I] = a[0, :, I]

      

This code calls the following ValueError

:

ValueError: Shape Mismatch: An array of shape values ​​(3,4) could not be passed to index the result of shape (3,4)

-

Following actions

Use caution when using a combination of slice and seq. whole numbers. As stated on github:

x = rand(3, 5, 7)

print(x[0, :, [0,1]].shape)
# (2, 5)

print(x[0][:, [0,1]].shape)
# (5, 2)

      

This is how numpy works, but it's still a little confusing that x [0] [:, I] is not the same as x [0,:, I]. Since this is the behavior I want, I want to use x [0] [:, I] in my code.

+1


source to share


3 answers


It looks like there are some mistakes when copying your code to the question.

But I suspect there is a known indexing issue:

In [73]: a=np.zeros((2,3,4)); b=np.ones((3,4)); I=np.array([0,1])

      

Make I

2 elements. Indexing b

gives the expected (3,2) shape. 3 rows from slice, 2 columns from I

indexing

In [74]: b[:,I].shape
Out[74]: (3, 2)

      

But with 3d a

we get a transposition.

In [75]: a[0,:,I].shape
Out[75]: (2, 3)

      

and the assignment will result in an error

In [76]: b[:,I]=a[0,:,I]
...
ValueError: array is not broadcastable to correct shape

      



First it puts the element size 2 being specified I

and 3 elements from the :

second. This is the case of the mixed forward indexing discussed earlier - and there is the bug issue. (I'll have to watch them).

You are probably using new numpy

(or scipy

) and getting a different error message.

He documented that indexing with two arrays or lists and a slice in the middle puts a slice at the end, for example.

In [86]: a[[[0],[0],[1],[1]],:,[0,1]].shape
Out[86]: (4, 2, 3)

      

The same thing happens with a[0,:,[0,1]]

. But there is a good argument that this should not be the case.

As for the fix, you can move the value or change the indexing

In [88]: b[:,I]=a[0:1,:,I]

In [90]: b[:,I]=a[0,:,I].T

In [91]: b
Out[91]: 
array([[ 0.,  0.,  1.,  1.],
       [ 0.,  0.,  1.,  1.],
       [ 0.,  0.,  1.,  1.]])

In [92]: b[:,I]=a[0][:,I]

      

https://github.com/numpy/numpy/issues/7030

https://github.com/numpy/numpy/pull/6256

+1


source


Here's how I get this error with indices [0,1,4]

:

IndexError: index 4 is out of bounds for axis 2 with size 4

      

Assumes the value is 4

used as an index, while SIZE 4 implies that the maximum index will be 3.



EDIT: now that you've changed it to [0, 1, 3]

, it works fine.

EDIT: With your current code, I get the same error, but when I print the arrays themselves, they are transverse:

print b[:, I]
print a[0, :, I]

[[ 1.  1.  1.]
 [ 1.  1.  1.]
 [ 1.  1.  1.]
 [ 1.  1.  1.]]

[[ 0.  0.  0.  0.]
 [ 0.  0.  0.  0.]
 [ 0.  0.  0.  0.]]

      

+1


source


First of all, it looks like line 6 is missing a comma:

I = sp.array([0,1,4])

      

Second, I would expect a value of 4 in the array I would raise an IndexError, since both a and b have a maximum size of 4. I suspect you can:

I = sp.array([0,1,3])

      

Making these changes runs the program for me and I got b as:

[[ 0.  0.  1.  0.]
 [ 0.  0.  1.  0.]
 [ 0.  0.  1.  0.]]

      

I suspect what you want.

+1


source







All Articles