Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multi dimensional array slice in one object

I have a numpy array:

arr = numpy.arange(25 * 10 * 20)
arr.resize((25, 10, 20))

I want to get slice like this:

arr[3:6, 2:8, 7:9]

This works:

index = [slice(3, 6), slice(2, 8), slice(7, 9)]
arr[index]

But this doesn't:

>>> index = slice([3, 2, 7], [6, 8, 9])
>>> arr[index]
TypeError: slice indices must be integers or None or have an __index__ method

Can it be done by ONE slice object? Or only list of 3 slices will work?

like image 212
Śmigło Avatar asked Sep 13 '25 23:09

Śmigło


2 Answers

>>> help(slice)
class slice(object)
 |  slice(stop)
 |  slice(start, stop[, step])

So we use slice(start, stop, step)

>>> import numpy as np
>>> x = np.arange(10)

## ERROR

>>> i=slice([1,3])
>>> x[i]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: slice indices must be integers or None or have an __index__ method

## OK

>>> i = slice(3,7,2)
>>> print(x)
[0 1 2 3 4 5 6 7 8 9]
>>> print(i)
slice(3, 7, 2)
>>> print(x[i])
[3 5]

For multi dimensional:

>>> x = np.arange(12).reshape(3,4)
>>> x
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>> i = slice(0,3,1)
>>> i
slice(0, 2, 1)
>>> x[i,i]
array([[0, 1],
       [4, 5]])
like image 157
Kinght 金 Avatar answered Sep 16 '25 13:09

Kinght 金


You can create a list of slices, zipping the two lists of indices:

>>> slices = [slice(*i) for i in zip([3,2,7], [6,8,9])]
>>> arr[slices]
array([[[ 647,  648],
    [ 667,  668],
    [ 687,  688],
    [ 707,  708],
    [ 727,  728],
    [ 747,  748]],

   [[ 847,  848],
    [ 867,  868],
    [ 887,  888],
    [ 907,  908],
    [ 927,  928],
    [ 947,  948]],

   [[1047, 1048],
    [1067, 1068],
    [1087, 1088],
    [1107, 1108],
    [1127, 1128],
    [1147, 1148]]])

Check with numpy.array_equal:

>>> numpy.array_equal(arr[slices], arr[3:6,2:8,7:9])
True
like image 41
grovina Avatar answered Sep 16 '25 11:09

grovina