Reputation: 31
A weird result occured when dealing with numpy advanced indexing. Is it a bug or numpy's constraint?
>>> a = np.arange(9).reshape((3,3,))
>>> a[0,1] # OK
1
>>> a[[0,1]] # OK
array([[0, 1, 2],
[3, 4, 5]])
>>> a[[[0,1]]] # ? (the result is 2-dim instead of 3-dim. just as same as a[[0,1]]. )
array([[0, 1, 2],
[3, 4, 5]])
>>> a[[[[0,1]]]] # ?
array([[[0, 1, 2],
[3, 4, 5]]])
I also tried the following, It's OK.
>>> a[[[0,1]],] # OK
array([[[0, 1, 2],
[3, 4, 5]]])
Upvotes: 2
Views: 73
Reputation: 2891
At case a[[[0,1]]]
you're passing a 2d-list into the index of a np.array
, which means it's equivalent to a[tuple([[0,1]])]
, which get further simplified into a[[0,1],]
. This triggers advanced indexing, so the result is of shape (2,3)
since you're literally stacking the 0-th and 1-th rows:
array([ [0, 1, 2], # 0-th row
[3, 4, 5] ]) # 1-th row
which has shape (2, 3)
.
On the other hand, a[[[[0,1]]]]
you're passing a 3d-list [...]. And instead the result is equivalent to a[([[0,1]], )]
, i.e. the first component of the tuple is 2d. By advanced indexing(again), you're just "wrapping an extra layer of []
to the result" or "pretending the shape of the result with a 1,
". This gives:
array([
[ # this is what you did: the extra layer
[0, 1, 2], # 0-th row
[3, 4, 5] # 1-th row
]
])
which has shape (1, 2, 3)
.
Upvotes: 0
Reputation: 231325
In a current version, 1.18
:
In [13]: a[[[0,1]]]
/usr/local/bin/ipython3:1: FutureWarning: Using a non-tuple sequence
for multidimensional indexing is deprecated; use `arr[tuple(seq)]`
instead of `arr[seq]`. In the future this will be interpreted as an
array index, `arr[np.array(seq)]`, which will result either in an
error or a different result.
#!/usr/bin/python3
Out[13]:
array([[0, 1, 2],
[3, 4, 5]])
In [14]: a[np.array([[0,1]])]
Out[14]:
array([[[0, 1, 2],
[3, 4, 5]]])
In [15]: _.shape
Out[15]: (1, 2, 3)
In other words, previous versions interpreted [13] as
In [16]: a[([0,1],)]
Out[16]:
array([[0, 1, 2],
[3, 4, 5]])
In [17]: _.shape
Out[17]: (2, 3)
In [18]: a[([[0,1]],)].shape
Out[18]: (1, 2, 3)
Numpy has been slowly cleaning up indexing edge cases, which were largely the result of merging several different numeric packages years ago.
===
Your comment case in readable form:
In [19]: a[[0,1],[0,1]]
Out[19]: array([0, 4])
In [20]: a[[[0,1],[0,1]]]
/usr/local/bin/ipython3:1: FutureWarning: Using a non-tuple sequence for multidimensional indexing is deprecated; use `arr[tuple(seq)]` instead of `arr[seq]`. In the future this will be interpreted as an array index, `arr[np.array(seq)]`, which will result either in an error or a different result.
#!/usr/bin/python3
Out[20]: array([0, 4])
In [21]: a[([0,1],[0,1])]
Out[21]: array([0, 4])
In [22]: a[[[[0,1],[0,1]]]]
/usr/local/bin/ipython3:1: FutureWarning: Using a non-tuple sequence for multidimensional indexing is deprecated; use `arr[tuple(seq)]` instead of `arr[seq]`. In the future this will be interpreted as an array index, `arr[np.array(seq)]`, which will result either in an error or a different result.
#!/usr/bin/python3
Out[22]:
array([[[0, 1, 2],
[3, 4, 5]],
[[0, 1, 2],
[3, 4, 5]]])
In [23]: a[np.array([[[0,1],[0,1]]])]
Out[23]:
array([[[[0, 1, 2],
[3, 4, 5]],
[[0, 1, 2],
[3, 4, 5]]]])
Upvotes: 3