Bozont
Bozont

Reputation: 25

NumPy: indexing one element from a 2D array

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?

Upvotes: 1

Views: 74

Answers (3)

Jacques Gaudin
Jacques Gaudin

Reputation: 17008

You could also use np.fromfunction together with np.vectorize:

np.fromfunction(np.vectorize(lambda i, j: [i,j] in filter_ind.tolist()), (8,8))

Upvotes: 0

yatu
yatu

Reputation: 88305

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

Upvotes: 5

GorillazOnPlane
GorillazOnPlane

Reputation: 401

When indexing like you want to, you have to give a tuple of indices, not an array of indices. Like this:

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

ind = ([0,1],[1,2]) #this is a tuple of lists, not a list of lists
print(a[ind]) # [2,6]

a[ind] = 0 #Setting a[0,1] = 0 and a[1,2] = 0
print(a) 

a:
[[1 0 3]
 [4 5 0]
 [7 8 9]]

Upvotes: 0

Related Questions