Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the default value of j in (i:j:k) numpy slicing?

I have been reading the tutorial of numpy i:j:k slicing at Scipy.org. After the second example, it says

Assume n is the number of elements in the dimension being sliced. Then, if i is not given it defaults to 0 for k > 0 and n - 1 for k < 0. If j is not given it defaults to n for k > 0 and -1 for k < 0. If k is not given it defaults to 1.

However:

>>> import numpy as np
>>> x = np.array([0,1,2,3,4])
>>> x[::-1]
array([4, 3, 2, 1, 0])

If j is defaulted to -1, then x[:-1:-1] should be equivalent to x[::-1], but

>>> x[:-1:-1]
array([], dtype=int64)
>>> x[:-(len(x)+1):-1]
array([4, 3, 2, 1, 0])

while

>>> x[:-(len(x)+1):-1]
array([4, 3, 2, 1, 0])

So the default value of j when k < 0 should be -(n+1). And according to this post on stackoverflow, I believe the "official" default value of j when k < 0 is None.

Am I misinterpreting the tutorial at SciPy.org?

like image 580
Xiangyu Avatar asked Jun 30 '15 18:06

Xiangyu


1 Answers

At the first level of processing, the Python interpreter converts :: notation into a slice object. It is up to the numpy.__getitem__ method to interpret those 3 numbers.

[::-1] is the same as slice(None,None,-1).

As you note, x[slice(None,None,-1)] is not the same as x[slice(None,-1,-1)].

I suspect that the -1 in:

If j is not given it defaults to n for k > 0 and -1 for k < 0 .

is not meant to be taken in that way. Rather it has the usual meaning of -1, the number before 0.

In [285]: np.arange(10)[slice(5,0,-1)] Out[285]: array([5, 4, 3, 2, 1])

j is interpreted as iterate upto, but not including, this value, with the direction of iteration determined by k. So the 0 value is not included in this slice.

So how do you include the 0?

In [287]: np.arange(10)[slice(5,-1,-1)]
Out[287]: array([], dtype=int32)

does not work because the -1 is understood to be n-1, as in:

In [289]: np.arange(10)[slice(5,-7,-1)]
Out[289]: array([5, 4])

None is interpreted in a special way that lets us use:

In [286]: np.arange(10)[slice(5,None,-1)]
Out[286]: array([5, 4, 3, 2, 1, 0])

This also works (10-11=-1 - the real -1)

In [291]: np.arange(10)[slice(5,-11,-1)]
Out[291]: array([5, 4, 3, 2, 1, 0])

So there's a distinction between -1 that means before 0, and -1 that means count from n. The documentation could be clear on this, but it's not wrong (if you use the right -1).

like image 106
hpaulj Avatar answered Oct 03 '22 01:10

hpaulj