1

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.

soubaboy
  • 13
  • 3

2 Answers2

1

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))
w-m
  • 10,772
  • 1
  • 42
  • 49
  • Oh I never heard about those submodules. I was considering something similar by reshaping and keeping only every other row but using a modulo feels a bit clearer – soubaboy Feb 10 '23 at 16:26
0

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])
mozway
  • 194,879
  • 13
  • 39
  • 75