Reputation: 31256
Suppose I have a CLI and would like to construct a slice from the CLI, where the CLI user just inputs a range string.
r = '1:4:2'
axis = '2'
And I have a way of slicing this as follows:
arr = np.zeros((10,10,10))
sliced_arr = eval("arr["+','.join([':',':',r])+"]")
Question: is there a better way to do this?
Upvotes: 2
Views: 83
Reputation: 26906
You can use something like this, which also supports negative index
s:
import numpy as np
def str2slicing(
slice_str: str,
index: int,
n_dim: int):
assert(-n_dim <= index < n_dim)
index %= n_dim
return tuple(
slice(*map(int, slice_str.split(':'))) if i == index else slice(None)
for i in range(n_dim))
arr = np.random.randint(1, 100, (10, 10, 10))
sliced_arr = arr[str2slicing('1:4:2', int('2'), arr.ndim)]
print(sliced_arr.shape)
# (10, 10, 2)
(Note that this is pretty much an extension / variation of the other answers: the juice is pretty much this slice(*map(int, slice_str.split(':')))
).
Upvotes: 0
Reputation: 221624
Here's one using r
and axis
as input arguments -
indexer = [slice(None)]*arr.ndim
indexer[int(axis)] = slice(*map(int,r.split(':')))
out = arr[tuple(indexer)]
Generalizing to handle to any generic indexing string notation in r
, it would be -
ax = int(axis)
indexer = [slice(None)]*arr.ndim
o = np.array([0,arr.shape[ax],1])
v = np.array(r.split(':'))
v = np.r_[v,['']*(len(o)-len(v))]
indexer[ax] = slice(*np.where(v=='',o,v).astype(int))
out = arr[tuple(indexer)]
Upvotes: 2
Reputation: 61920
You could build a slice object from the string, and then use numpy.s_:
import numpy as np
r = '1:4:2'
arr = np.zeros((10,10,10))
s = slice(*map(int, r.split(":")))
print(s)
sliced_arr = arr[np.s_[:, :, s]]
Output
slice(1, 4, 2)
Upvotes: 1