Reputation: 165
Sample code:
import numpy as np
a = np.zeros((5,5))
a[[0,1]] = 1 #(list of indices)
print('results with list based indexing\n', a)
a = np.zeros((5,5))
a[(0,1)] = 1 #(tuple of indices)
print('results with tuple based indexing\n',a)
Result:
results with list based indexing
[[ 1. 1. 1. 1. 1.]
[ 1. 1. 1. 1. 1.]
[ 0. 0. 0. 0. 0.]
[ 0. 0. 0. 0. 0.]
[ 0. 0. 0. 0. 0.]]
results with tuple based indexing
[[ 0. 1. 0. 0. 0.]
[ 0. 0. 0. 0. 0.]
[ 0. 0. 0. 0. 0.]
[ 0. 0. 0. 0. 0.]
[ 0. 0. 0. 0. 0.]]
As you must have noticed, indexing array with list gave a different result than with tuple of same indices. I'm using python3 with numpy version 1.13.3
What is the fundamental difference in indexing a numpy array with list and tuple?
Upvotes: 5
Views: 172
Reputation: 165
I also tried following cases in terminal.
a[[0],[1]] = 1
a[(0),(1)] = 1
a[(0,),(1,)] = 1
All of them are equivalent to a[0,1] = 1
.
What I understood from this is that, Numpy is expecting N different sequences of integers for indexing N dimensions of array.
Meaning, indexing array as a[[ 0,1 ]]
results in a[ [0,1], :]
.
[0,1]
is taken as a one sequence of integers to access first dimension of the array and since no indexing is mentioned for remaining dimension it is taken as:
by default which results in a[[0,1],:]
.
Answer by wim gave me a direction for this thought.
Cheers!
Upvotes: 0
Reputation: 362796
By design. Numpy's getitem and setitem syntax does not duck-type, because the different types are used to support different features. This is just a plain old __setitem__
:
a[(0,1)] = 1
It's the same as doing a[0,1] = 1
. In both cases, ndarray's setitem receives two arguments: a tuple for the index (0, 1)
and the value 1
.
a[[0,1]] = 1
This is a special case of broadcasting. It would usually be written a[0:2] = 1
, but you could also slice/mutate other rows for example a[[0,1,3]]
. The scalar 1
gets "stretched" across all columns of rows 0 and 1 in the assignment.
Upvotes: 7