1

I have a numpy array a = np.arange(100) including 100 numbers. I wondered to know is there a way to slice it periodically rather than using the conditional statements.

for example, if I want to slice the 1st four numbers + 5th four numbers + 9th four numbers and so on and finally have all these in one array.

any suggestions?

thanks

  • have a look at advanced indexing, that may help – anon01 Nov 21 '20 at 05:04
  • actually, it's not clear what you're asking for. We can surely help if you provide an example of expected output – anon01 Nov 21 '20 at 05:17
  • sure, let say I have an array [1 2 3 ... 99 100] and I want to take out these numbers which occur periodically (1 2 3 4 17 18 19 20 33 34 35 36 ...). the numbers are following a pattern which is 1st four-numbers + 5th four-numbers + 9th four-numbers and so on. –  Nov 21 '20 at 05:26

3 Answers3

1

Code:

import numpy as np

a = np.arange(100)
grp = 4
grp_no = [1,5,9]
lst = np.array([a[range(n*grp-4, n*grp)] for n in grp_no])
print(lst)
print(lst.flatten()) #if required

Output:

[[ 0  1  2  3]
 [16 17 18 19]
 [32 33 34 35]]
[ 0  1  2  3 16 17 18 19 32 33 34 35]
Aaj Kaal
  • 1,205
  • 1
  • 9
  • 8
  • thanks for your reply. I am looking for a more comprehensive method. My real dataset is very big and I want to continue slicing to the last numbers in my array. –  Nov 21 '20 at 05:32
  • One liner and truly pythonic solution. Can you please detail what do you mean by comprehensive ? Thanks – Aaj Kaal Nov 22 '20 at 12:35
0

You want a strided index - I don't know of numpy tooling that does that completely vectorized, but it probably exists.

This solution selects indices idx_arr from a. The only un-vectorized (slow) component is the loop over stride groups; everything else should be fast. Notice in particular pre-populating :

nmax = 10000
m = 4
a = np.random.rand(nmax)
_sub_arr = np.arange(m)
idx_arr = np.concatenate([_sub_arr + 4*m for m in range(0, int(nmax/m), 4)])
sol = a[idx_arr]
print(sol)
anon01
  • 10,618
  • 8
  • 35
  • 58
0

You can use np.resize to transform the array into two dimensions, then slice the rows as required. Just be wary that there is an edge case if a is not an exact multiple of 4.

import numpy as np

wt = 4
a = np.arange(100)
ht = int(a.size/wt)
a.resize(ht, wt)
n = a[0::4,].flatten()
print(n)

Output:

[ 0  1  2  3 16 17 18 19 32 33 34 35 48 49 50 51 64 65 66 67 80 81 82 83
 96 97 98 99]
Patrick
  • 16
  • 2
  • thanks for your solution, I think that is the best way to do that as I couldn't find any other ways. –  Nov 23 '20 at 05:28