9

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.

3
  • 1
    I don't know if this is possible . Or do you want this a_sub = b[range(0,100)+range(200,300)+range(400,500)] Commented Nov 21, 2015 at 6:22
  • I mean you can't index a list like that in a line specifically a_sub = a[(0:100, 200:300, 400:500)] Commented Nov 21, 2015 at 6:24
  • Did any of the solutions posted here work for you? Commented Nov 23, 2015 at 13:54

6 Answers 6

3

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()
Sign up to request clarification or add additional context in comments.

1 Comment

Note that this solution only works for interval of constant size and spacing (one interval of size 100 every 100 items) as in the OP's example.
2

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).

Comments

2

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])

Comments

1

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)

Comments

0

two others one-liner :

[x for i,x in enumerate(a) if i//100%2==0] #python
b[np.arange(len(b))//100%2==0] # numpy

Comments

0

or using hstack (+ adds the values element wise)

a = np.arange(1000)
limits = [(0, 100), (200, 300), (400, 500)]
b = np.hstack(a[low:high] for low, high in limits)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.