Josh Flori
Josh Flori

Reputation: 415

Slice list where index values are strings?

I have loaded a black and white image as a numpy array. The array shape is equal to the pixels in the image. I want to extract certain ranges of pixel values, for instance,

numpy_array_to_slice[160:300,28:43] 

etc etc, but I don't want to hardcode the index numbers. Rather, I want to load the index values from a list of values. For instance, I have a list of index values like:

listofindexvalues = [['160:300,28:43'],['160:300,40:55'],['160:300,28:43']] 

So effectively I want something like:

numpy_array_to_slice[listofindexvalues[0]]

which would take the place of:

numpy_array_to_slice['160:300,28:43']

I've tried a variety of things which haven't worked like:

first,second = str(index_list[19]).replace('[','').replace(']','').replace('\'','').split(':')  ##for just one side of an index value, such as 28:59

and trying to pass that like so:

numpy_array_to_slice[int(first)+':'+int(second]

but that doesn't work because I can't concatenate those values. Is there any way to accomplish this?

Upvotes: 1

Views: 479

Answers (2)

Martijn Pieters
Martijn Pieters

Reputation: 1124040

Slicing is syntax, not a string. See the Slicings expressions reference documentation:

The semantics for a slicing are as follows. The primary is indexed (using the same __getitem__() method as normal subscription) with a key that is constructed from the slice list, as follows. If the slice list contains at least one comma, the key is a tuple containing the conversion of the slice items; otherwise, the conversion of the lone slice item is the key. The conversion of a slice item that is an expression is that expression. The conversion of a proper slice is a slice object (see section The standard type hierarchy) whose start, stop and step attributes are the values of the expressions given as lower bound, upper bound and stride, respectively, substituting None for missing expressions.

Bold emphasis mine.

You can bypass this conversion (from slice syntax to slice() objects) by creating slice() objects directly; you can put them in tuples if need be.

So

numpy_array_to_slice[160:300,28:43]

is equivalent to

box = slice(160, 300), slice(28, 43)
numpy_array_to_slice[box]

I've omitted the step argument; it defaults to None when omitted.

Extending this to your list would be:

listofindexvalues = [
    (slice(160, 300), slice(28, 43)),
    (slice(160, 300), slice(40, 55)),
    (slice(160, 300), slice(28, 43))
]

for box in listofindexvalues:
    sliced_array = numpy_array_to_slice[box]

Upvotes: 5

timgeb
timgeb

Reputation: 78770

You should use a list of slice instances (or tuples thereof), not strings.

Here's an example.

>>> import numpy as np
>>> 
>>> listofindexvalues = [(slice(1, 6), slice(3, 4))]
>>> a = np.arange(100).reshape(10,10)
>>> a[listofindexvalues[0]]
array([[13],
       [23],
       [33],
       [43],
       [53]])

a[listofindexvalues[0]] is equivalent to a[1:6, 3:4] in this case.

>>> a[1:6, 3:4]
array([[13],
       [23],
       [33],
       [43],
       [53]])

Upvotes: 1

Related Questions