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)]
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.
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].
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.
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.
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.
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]]])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With