Numpy Array: Slice several values at every step

Question:

I am trying to extract several values at once from an array but I can’t seem to find a way to do it in a one-liner in Numpy.

Simply put, considering an array:

a = numpy.arange(10)
> array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

I would like to be able to extract, say, 2 values, skip the next 2, extract the 2 following values etc. This would result in:

array([0, 1, 4, 5, 8, 9])

This is an example but I am ideally looking for a way to extract x values and skip y others.

I thought this could be done with slicing, doing something like:

a[:2:2]

but it only returns 0, which is the expected behavior.

I know I could obtain the expected result by combining several slicing operations (similarly to Numpy Array Slicing) but I was wondering if I was not missing some numpy feature.

Asked By: soubaboy

||

Answers:

You can use a modulo operator:

x = 2 # keep
y = 2 # skip

out = a[np.arange(a.shape[0])%(x+y)<x]

Output: array([0, 1, 4, 5, 8, 9])

Output with x = 2 ; y = 3:

array([0, 1, 5, 6])
Answered By: mozway

If you want to avoid creating copies and allocating new memory, you could use a window_view of two elements:

win = np.lib.stride_tricks.sliding_window_view(a, 2)

array([[0, 1],
       [1, 2],
       [2, 3],
       [3, 4],
       [4, 5],
       [5, 6],
       [6, 7],
       [7, 8],
       [8, 9]])

And then only take every 4th window view:

win[::4].ravel()

array([0, 1, 4, 5, 8, 9])

Or directly go with the more dangerous as_strided, but heed the warnings in the documentation:

np.lib.stride_tricks.as_strided(a, shape=(3,2), strides=(32,8))
Answered By: w-m