Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Selecting multiple slices from a numpy array at once

Tags:

I'm looking for a way to select multiple slices from a numpy array at once. Say we have a 1D data array and want to extract three portions of it like below:

data_extractions = []  for start_index in range(0, 3):     data_extractions.append(data[start_index: start_index + 5]) 

Afterwards data_extractions will be:

data_extractions = [     data[0:5],     data[1:6],     data[2:7] ] 

Is there any way to perform above operation without the for loop? Some sort of indexing scheme in numpy that would let me select multiple slices from an array and return them as that many arrays, say in an n+1 dimensional array?


I thought maybe I can replicate my data and then select a span from each row, but code below throws an IndexError

replicated_data = np.vstack([data] * 3) data_extractions = replicated_data[[range(3)], [slice(0, 5), slice(1, 6), slice(2, 7)] 
like image 285
Puchatek Avatar asked Apr 14 '17 14:04

Puchatek


People also ask

How do I slice a NumPy array in Python?

You can slice a range of elements from one-dimensional numpy arrays such as the third, fourth and fifth elements, by specifying an index range: [starting_value, ending_value]. Note that the index structure is inclusive of the first index value, but not the second index value.

How to select the third element in a NumPy array?

You can use avg_monthly_precip [2] to select the third element in ( 1.85) from this one-dimensional numpy array. Recall that you are using use the index [2] for the third place because Python indexing begins with [0], not with [1].

How to slice elements from two-dimensional arrays?

To slice elements from two-dimensional arrays, you need to specify both a row index and a column index as [row_index, column_index]. For example, you can use the index [1,2] to query the element at the second row, third column in precip_2002_2013.

How to use slicing in Python?

Slicing in python means taking elements from one given index to another given index. We pass slice instead of index like this: [ start: end]. We can also define the step, like this: [ start: end: step]. If we don't pass start its considered 0. If we don't pass end its considered length of array in that dimension.


2 Answers

You can use the indexes to select the rows you want into the appropriate shape. For example:

 data = np.random.normal(size=(100,2,2,2))   # Creating an array of row-indexes  indexes = np.array([np.arange(0,5), np.arange(1,6), np.arange(2,7)])  # data[indexes] will return an element of shape (3,5,2,2,2). Converting  # to list happens along axis 0  data_extractions = list(data[indexes])   np.all(data_extractions[1] == data[1:6])  True 

The final comparison is against the original data.

like image 101
tmrlvi Avatar answered Sep 19 '22 15:09

tmrlvi


stride_tricks can do that

a = np.arange(10) b = np.lib.stride_tricks.as_strided(a, (3, 5), 2 * a.strides) b # array([[0, 1, 2, 3, 4], #        [1, 2, 3, 4, 5], #        [2, 3, 4, 5, 6]]) 

Please note that b references the same memory as a, in fact multiple times (for example b[0, 1] and b[1, 0] are the same memory address). It is therefore safest to make a copy before working with the new structure.

nd can be done in a similar fashion, for example 2d -> 4d

a = np.arange(16).reshape(4, 4) b = np.lib.stride_tricks.as_strided(a, (3,3,2,2), 2*a.strides) b.reshape(9,2,2) # this forces a copy # array([[[ 0,  1], #         [ 4,  5]],  #        [[ 1,  2], #         [ 5,  6]],  #        [[ 2,  3], #         [ 6,  7]],  #        [[ 4,  5], #         [ 8,  9]],  #        [[ 5,  6], #         [ 9, 10]],  #        [[ 6,  7], #         [10, 11]],  #        [[ 8,  9], #         [12, 13]],  #        [[ 9, 10], #         [13, 14]],  #        [[10, 11], #         [14, 15]]]) 
like image 27
Paul Panzer Avatar answered Sep 17 '22 15:09

Paul Panzer