Reputation: 1047
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 slice
s will work?
Upvotes: 4
Views: 2745
Reputation: 21947
Is np.s_
, "A nicer way to build up index tuples for arrays", what you want ?
A = np.arange( 25 * 10 * 20 ).reshape( 25, 10, 20 )
region = np.s_[ 3:6, 2:8, 7:9 ]
# (slice(3, 6, None), slice(2, 8, None), slice(7, 9, None))
A[region] # your arr[slices], shape (3, 6, 2)
(would be nice if the doc for np.s_ had such an example, not just 1d.)
Upvotes: 0
Reputation: 749
Can it be done by ONE slice object?
No, slice objects are one-dimensional.
Or only list of 3 slices will work?
A list of 3 slices will not work as of v1.23.0. Multidimensional indexing with non-tuple values has been deprecated since v1.15 and expired in v1.23.0 (see this section of the changelog).
As of v1.23.0, the only way to specify a multidimensional slice with a single object is to use a tuple of slice objects. If you would like to use [:]
notation, you can create a tuple of slice objects using numpy.s_
. In OP's case:
>>> numpy.s_[3:6, 2:8, 7:9]
(slice(3, 6, None), slice(2, 8, None), slice(7, 9, None))
Upvotes: 1
Reputation: 3077
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
Upvotes: 1
Reputation: 18341
>>> 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]])
Upvotes: 1