user3317287
user3317287

Reputation: 429

A confusion of indexing/slicing a numpy array

I have a clarification to make when slicing through numpy arrays.

Suppose I want to slice an array with the index counting down from some higher value to the first index. For example, a = np.zeros(10)

If I do a[5::-1], I get array([ 0., 0., 0., 0., 0., 0.]), but why when I do a[5:-1:-1], I get the following array([], dtype=float64). I don't understand the logic behind it. It is important for me to specify the last index. On the other hand if I want the first 5 entries of this array, both a[0:5:1] and a[:5:1] give me the same result. What is wrong in using the -1 as the index?

On a side note, how do I obtain the union of two disjoint slices?

Thanks

Upvotes: 2

Views: 1927

Answers (2)

tom10
tom10

Reputation: 69192

To slice backwards with last index -1, you need your start index to be larger than your stop index, so:

import numpy as np
a = 10+np.arange(10)

print a[-1:5:-1]   # [19 18 17 16]
print a[6:][::-1]  # [19 18 17 16]  A less confusing alternative

How does this make sense:

First a negative step always means "stepping towards smaller indices". So to list an array with a negative step, the first index must be larger than that last. This gets a bit confusing when negative indices are used, but here, as elsewhere, one must think of negative step as "interpreted as n+step". After all, stepping in a positive direction from 5 to -1, makes no more sense than than stepping in a negative direction from -1 to 5; both only make sense by the understanding that -1 is interpreted as n-1.

What is intrinsically confusing about reverse stepping is the Python policy of not including the end element in a a[start:end]. In general, this allows for much cleaner indexing, but here one has to explicitly deal with this issue since what was the end point (and was excluded) is now the start point (and is included). That is, a[5:-1:-1] is not the reverse of a[-1:5:-1].

Given that I want to think about these endpoint issues as little as possible, I usually just do what I have above as the less confusing option.

(All quotes in above are taken from here).

Upvotes: 1

Kevin
Kevin

Reputation: 30151

In Python, by convention the index -1 refers to the last element of the array. -2 is the next-to-last, and so on. When you slice from 5 to -1, that's equivalent to the slice [5:9] for an array of length 10. When you add a -1 step, you're saying "slice downwards from 5 to 9." But that's nonsensical since 5 is below 9, so you get an empty list.

On a side note, how do I obtain the union of two disjoint slices?

itertools.chain().

Upvotes: 5

Related Questions