0

I realize that arr[::-1] returns a reversed view for arr. Further arr[st_index:end_index:increment] is a compact syntax for indexing while creating view. (BTW what is this way of indexing called?)

So if I have code like:

arr = np.array(range(10))
print(arr)  #prints: [0 1 2 3 4 5 6 7 8 9]

Now, if I want to see the arr as reversed I can try (I don’t need to subtract 1 from len(arr)):

arr[len(arr)-1: 0: -1] #This gives o/p as: array([9, 8, 7, 6, 5, 4, 3, 2, 1])

The first element was not selected, which was expected. And if I change 0 to -1, i.e, if I try: arr[len(arr)-1: -1: -1] OR even arr[:-1:-1], I get an empty array.

Apparently I get the reversed array view by: arr[::-1]

Q: How is this working? If I do not specify the first two arguments how does it infer that it needs to continue till 0? In fact it is just interpreting that it needs to go till the boundary as arr[::1] gives normal array.

Is this just coded as a special case or is there something more going on? And is there a way to get reversed array view by explicitly specifying the three expressions in indexing. i.e., are there any values for expr1, expr2, expr3 which can reverse arr in arr[expr1:expr2:expr3]?

user1953366
  • 1,341
  • 2
  • 17
  • 27
  • *"what is this way of indexing called?"* - This is called [*slicing*](https://docs.python.org/3/reference/expressions.html?highlight=slice#slicings). – 0x5453 Jan 13 '21 at 15:33
  • 1
    Especially the answer https://stackoverflow.com/a/509297/480982 of that question – Thomas Weller Jan 13 '21 at 15:44
  • Q: If I do not specify the first two arguments how does it infer that it needs to continue till 0? A: it internally sets the end to `-1`, but this is only triggered by passing `None`, you can't set it explicitly, see [source of `PySlice_GetIndices`](https://github.com/python/cpython/blob/61d8c54f43a7871d016f98b38f86858817d927d5/Objects/sliceobject.c#L191) – Stef Jan 13 '21 at 21:14

1 Answers1

0

This is basic Python slice behavior:

In [1]: 'abc'[::-1]
Out[1]: 'cba'
In [2]: 'abc'[slice(None,None,-1)]
Out[2]: 'cba'

numpy has an 'indexing_tricks` object that can convert the slice notation to a slice object:

In [3]: np.s_[::-1]
Out[3]: slice(None, None, -1)
In [4]: np.s_[:-1]                # the common 'all but last' slice
Out[4]: slice(None, -1, None)

The interpreter converts the :: notation to a slice object, using None for the omitted values. The object's __getitem__ method is responsible for using the slice (or tuple containing slices). The correct start and stop can be inferred from the object's dimensions.

hpaulj
  • 221,503
  • 14
  • 230
  • 353