NumPy: indexing one element from a 2D array

Bozont :

I have the following 8 by 8 array named arr:

[[False False False False False False False False]
 [False False False False False False False False]
 [False False False False False False False False]
 [False False False False False False False False]
 [False False False False False False False False]
 [False False False False False False False False]
 [False False False False False False False False]
 [False False False False False False False False]]

I want to set specific elements of it to True, for which I have this filtered_ind array:

[[5 6]
 [4 5]
 [2 5]
 [1 6]]

Trying to do this:

arr[filtered_ind] = True

Results in the following:

[[False False False False False False False False]
 [ True  True  True  True  True  True  True  True]
 [ True  True  True  True  True  True  True  True]
 [False False False False False False False  True]
 [ True  True  True  True  True  True  True  True]
 [ True  True  True  True  True  True  True  True]
 [ True  True  True  True  True  True  True  True]
 [False False False False False False False False]]

Basically, it takes every number in the filtered_ind array, and sets those rows to True, instead of setting the specific elements.

I figured out that the indexing does not work the way I think it does, since print(arr[filtered_ind]) gives me this:

[[[False False False False False False False False]
  [False False False False False False False False]]

 [[False False False False False False False False]
  [False False False False False False False False]]

 [[False False False False False False False False]
  [False False False False False False False False]]

 [[False False False False False False False False]
  [False False False False False False False False]]]

instead of what I expect, which would be [False False False False] of course.

How do I fix this, and more importantly, why is this happening?

yatu :

You're only indexing along the first axis. You need:

a = np.full((8,8), False)
ix = np.array([[5, 6],[4, 5],[2, 5],[1, 6]])

a[ix[:,0], ix[:,1]] = True

Or we could also use np.add.at here:

np.add.at(a,tuple(zip(*ix)),True)

print(a)
[[False False False False False False False False]
 [False False False False False False  True False]
 [False False False False False  True False False]
 [False False False False False False False False]
 [False False False False False  True False False]
 [False False False False False False  True False]
 [False False False False False False False False]
 [False False False False False False False False]]

Keep in mind, that by indexing as you are, a[ix], you are indexing only along the first axis. You'll see more clearly with a simpler example:

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

a = np.arange(0,16).reshape(4,4)
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])

Now if you index along the first axis, as you were doing, you get:

a[ix]

array([[[ 4,  5,  6,  7],
        [ 8,  9, 10, 11]],

       [[ 0,  1,  2,  3],
        [12, 13, 14, 15]],

       [[ 8,  9, 10, 11],
        [ 8,  9, 10, 11]]])

Basically as many rows as values in the indices, with the shape of the indexing array. You must also specify along which columns (second axis) you're indexing, so as in the first approach, [ix[:,0] along the first axis and ix[:,1] along the second:

a[ix[:,0], ix[:,1]] = True

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=398390&siteId=1