Number945
Number945

Reputation: 4940

Numpy array documentation slicing rule

In Basic slicing of numpy array http://docs.scipy.org/doc/numpy-1.5.x/reference/arrays.indexing.html#basic-slicing,
I found the following rule which does not work for the example I shown below.

Rule: 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 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. Note that :: is the same as : and means select all indices along this axis.

What I understood : This can be prioritized as top to down :

a)If k is not given it defaults to 1.
b)If j is not given it defaults to n for k > 0 and -1 for k < 0 .
c)if i is not given it defaults to 0 for k > 0 and n for k < 0.

Now let's see the example. Basically what I am doing is to take a 3d array and print it bottom up . Layer with largest index comes first and then the smaller one. Please look at code for better understanding.

import numpy as np

b= np.arange(24).reshape(2,3,4)
print "Here is the input :" 
print b
print

print "Here is what is desired output :"
print b[::-1 , :: ,::]
print 

print "Here is what I want to get desired output by a different way using above rule :"
print b[2:-1:-1 , :: , ::]

Output :

Here is the input :
[[[ 0  1  2  3]
  [ 4  5  6  7]
  [ 8  9 10 11]]

 [[12 13 14 15]
  [16 17 18 19]
  [20 21 22 23]]]

Here is what is desired output :
[[[12 13 14 15]
  [16 17 18 19]
  [20 21 22 23]]

 [[ 0  1  2  3]
  [ 4  5  6  7]
  [ 8  9 10 11]]]

Here is what I want to get desired output by a different way using above rule :
[]

Is b[::-1 , :: ,::] not same as b[2:-1:-1 , :: , ::] by above rule?

Upvotes: 4

Views: 259

Answers (2)

HYRY
HYRY

Reputation: 97291

The document is right, but it doesn't means that you can use the calculated start, end index in slice object again. It only tells you the logic to calculate the start & end index. To use the calculated index, you need to generate the index by range():

Here is an example:

import numpy as np
s = slice(None, None, -1)
t = np.array([1, 2, 3, 4])
s.indices(len(t))

outputs:

(3, -1, -1)

so the (start, stop, stride) of [::-1] for a four element array is (3, -1, -1), but t[3:-1:-1] is empty. The (start, stop, stride) is for range(), So, you can use t[range(3,-1,-1)] which is [4, 3, 2, 1].

Upvotes: 2

hpaulj
hpaulj

Reputation: 231385

With a negative step, you need to think twice about the start and stop values.

A simple reverse:

In [437]: np.arange(10)[::-1]
Out[437]: array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])

start at the end - same thing

In [438]: np.arange(10)[10::-1]
Out[438]: array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])

with -1 stop, empty

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

but with -2, it returns the last value; remember it's counting from the end, and -2 also counts from the end.

In [440]: np.arange(10)[10:-2:-1]
Out[440]: array([9])

last 4 items:

In [441]: np.arange(10)[10:-5:-1]
Out[441]: array([9, 8, 7, 6])

all but the first:

In [442]: np.arange(10)[10:-10:-1]
Out[442]: array([9, 8, 7, 6, 5, 4, 3, 2, 1])

same with 0:

In [445]: np.arange(10)[10:0:-1]
Out[445]: array([9, 8, 7, 6, 5, 4, 3, 2, 1])

you have to use None to get everything:

In [446]: np.arange(10)[10:None:-1]
Out[446]: array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])

Upvotes: 1

Related Questions