Reputation: 25
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
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
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
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