Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Index multiple items of array with intervals in Python

Suppose that I have a list:

import numpy as np
a = [2, 4, 6, 8, ..., 1000] # total 500 elements
b = np.array(a)             # numpy version

I want to get 1st to 100th, 201st to 300th, 401st to 500th elements and make them into a new array.

To this end, I've tried the following codes:

a_sub = a[0:100] + a[200:300] + a[400:500]
b_sub = np.concatenate((b[0:100], b[200:300], b[400:500]))

But I want to do it with a simple oneline-indexing

Say:

a_sub = a[(0:100, 200:300, 400:500)]
a_sub = a[[0:100, 200:300, 400:500]]
b_sub = b[[0:100, 200:300, 400:500]]
b_sub = b[[0:100, 200:300, 400:500]]

But the above are all invalid and I couldn't find such a oneliner indexing.

like image 451
Jeon Avatar asked Nov 21 '15 05:11

Jeon


4 Answers

You can convert the slices to a mask-array (by slicing an ones-array), and union the mask-arrays using the | (or) operator.

ones = np.ones(b.shape, dtype = bool)
mask = ones[ 0:100] | ones[200:300] | ones[400:500]
b_sub = b[mask]

Note that if your slices overlap, or appear in a non-increasing order, this results with a different array than your original code (items will not repeat, and will always appear in the same order as in the original array).

like image 28
shx2 Avatar answered Nov 12 '22 20:11

shx2


You could use reshaping with np.reshape and slicing, like so -

np.array(a).reshape(-1,100)[::2].ravel()

If a is a NumPy array, you could do like so -

a.reshape(-1,100)[::2].ravel()
like image 185
Divakar Avatar answered Nov 12 '22 22:11

Divakar


You could also use np.split:

a = range(2, 1002, 2)
edges = [100, 200, 300, 400]
subarrays = np.split(a, edges)
b = np.hstack(subarrays[i] for i in [0, 2, 4])
like image 22
ali_m Avatar answered Nov 12 '22 22:11

ali_m


well, it is pure python, but maybe it may solve your question

a = [2, 4, 6, 8, ..., 1000]
slices = ((0, 100), (200, 300), (400, 500))

def new_from_slices(list_, slices):
    return list(itertools.chain(*[list_[s[0]:s[1]] for s in slices]))
new_from_slices(a, slices)
like image 43
Andrey Rusanov Avatar answered Nov 12 '22 20:11

Andrey Rusanov