-1

I wonder if there is a fancy numpy indexing to perform this operation. If I have an array and two limits it is easy to index with colon:

import numpy as np

myArray = np.arange(10)

lowLimit = 2
highLimit = 5

print myArray[lowLimit:highLimit]

which gives [2 3 4]. However, if you have two arrays for the limits:

lowLimit = np.ones(10) * 2
highLimit = np.ones(10) * 5

The previous operation does not work.

How would you get a 2D array with the sliced regions of myArray?:

array([[2, 3, 4],
       [2, 3, 4],
       [2, 3, 4],
       [2, 3, 4],
       [2, 3, 4],
       [2, 3, 4],
       [2, 3, 4],
       [2, 3, 4],
       [2, 3, 4],
       [2, 3, 4]])

UPDATE: In this example the limit arrays have a constant value but that might not be the case.

Delosari
  • 677
  • 2
  • 17
  • 29
  • Your question is not very clear. Do you want a method that works when the `lowLimit` and `highLimit` arrays are not repeats of just one value? You should give a better, more general, example if that is what you mean. For this to result in a numpy array, however, each slice must have the same number of elements, which is a serious limitation. – Rory Daulton Jul 19 '18 at 23:20
  • You can't *create* data with indexing, you can only *select* it. It looks like you want to take a slice of a 1-d array and concatenate that slice into a 2-d array. `...the limits might not have a constant value...` - you will have to explain that better in your question. – wwii Jul 20 '18 at 03:31

3 Answers3

2

One way or other you have concatenate/join some slices:

In [139]: x = np.arange(10)
In [140]: low,high = [0,3,5,3],[2,5,7,5]

A list comprehension:

In [141]: [x[i:j] for i,j in zip(low,high)]
Out[141]: [array([0, 1]), array([3, 4]), array([5, 6]), array([3, 4])]

Since all slices have the same size, they can be concatenated into a new array:

In [142]: np.stack(_)
Out[142]: 
array([[0, 1],
       [3, 4],
       [5, 6],
       [3, 4]])

If they differed in length, stack won't work. np.array(_) would produce an object dtype array, with component arrays of varying length.

You could also generate an array of all indices, and use that:

In [160]: np.hstack([np.r_[slice(i,j)] for i,j in zip(low,high)])
Out[160]: array([0, 1, 3, 4, 5, 6, 3, 4])
In [161]: x[_].reshape(4,2)     # reshape if all slices are same length:
Out[161]: 
array([[0, 1],
       [3, 4],
       [5, 6],
       [3, 4]])
hpaulj
  • 221,503
  • 14
  • 230
  • 353
1

numpy.vstack?

import numpy as np
myArray = np.arange(10)

lowLimit = 2
highLimit = 5
n = 10

z = myArray[lowLimit:highLimit]
q = np.vstack((z,)*n)

OR numpy.tile:

q = np.tile(z, n).reshape(n, z.shape[0])
wwii
  • 23,232
  • 7
  • 37
  • 77
  • Thank you @wwii very much for your reply. I meant however a more general case where the limits might not have a constant value. I have updated the answer. (Maybe it cannot be done with fancy indexing... What do you think?) – Delosari Jul 19 '18 at 23:49
0

do you want a list of arrays with variate length?

here is an anwser that may helps:

low_limit=np.random.randint(1,4,10)
high_limit=low_limit+np.random.randint(3,9,10)

result=[]
for i in range(len(low_limit)):
    result.append(my_array[low_limit[i]:high_limit[i]])
result

The result is:

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

This is a good reference, hope it can solve your problem. How to make a multidimension numpy array with a varying row size?

smartass
  • 26
  • 4