The easiest way to explain my question may be with an example, so let me define some arrays:
>>> test = arange(25).reshape((5,5))
>>> test
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14],
[15, 16, 17, 18, 19],
[20, 21, 22, 23, 24]])
>>> Xinds = array([1,2,3])
>>> Yinds = array([1,2,3])
Now, if I wanted the elements in rows 1, 2, and 3 and in column 0, I could go:
>>> test[Yinds,0]
array([ 5, 10, 15])
If I wanted the items in rows 1, 2, and 3 and all columns, I could go:
>>> test[Yinds, :]
array([[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14],
[15, 16, 17, 18, 19]])
However, if I try to extend this to get the elements in rows 1, 2, and 3 and columns 1, 2, and 3, -- surprise! -- I instead get the elements in (1,1), (2,2), and (3,3)
>>> test[Yinds, Xinds]
array([ 6, 12, 18])
Instead of what I want:
>>> test[Yinds, :][:, Xinds]
array([[ 6, 7, 8],
[11, 12, 13],
[16, 17, 18]])
>>> test[1:4,1:4]
array([[ 6, 7, 8],
[11, 12, 13],
[16, 17, 18]])
I realize I could define a slice, but I want to be able to add an offset to the indices (e.g. Yinds+offset), and that can't be done with slices.
I could do something like
>>> xStart = 1
>>> xEnd = 4
>>> yStart = 1
>>> yEnd = 4
>>> offset = 1
>>> test[yStart+offset:yEnd+offset, xStart+offset:xEnd+offset]
...
or
>>> Xinds = array([1,4])
>>> Yinds = array([1,4])
>>> offset = 1
>>> test[slice(*(Yinds+offset)), slice(*(Xinds+offset))]
...
But neither is particular clean.
Monkey patching the addition operator in to slice doesn't seem to be an option, and inheriting from slice to add the operator doesn't appear to work either; I get the error, "type 'slice' is not an acceptable base type". (*Grumble* This wouldn't be a problem in Ruby *Grumble*)
So, my question is, what's the cleanest way to access a (more than 1 dimensional) sub-array with something that can be stored and offset?
Options so far:
ndarrays can be indexed using the standard Python x[obj] syntax, where x is the array and obj the selection. There are different kinds of indexing available depending on obj: basic indexing, advanced indexing and field access.
Fancy indexing is conceptually simple: it means passing an array of indices to access multiple array elements at once. For example, consider the following array: import numpy as np rand = np. random. RandomState(42) x = rand.
We can also index NumPy arrays using a NumPy array of boolean values on one axis to specify the indices that we want to access. This will create a NumPy array of size 3x4 (3 rows and 4 columns) with values from 0 to 11 (value 12 not included).
Numpy with Python Three types of indexing methods are available − field access, basic slicing and advanced indexing. Basic slicing is an extension of Python's basic concept of slicing to n dimensions. A Python slice object is constructed by giving start, stop, and step parameters to the built-in slice function.
I'm not entirely sure what you want, but maybe ix_
would help? I think I've seen people who know more about numpy than I do use it in similar contexts.
>>> from numpy import array, arange, ix_
>>> a = arange(25).reshape(5,5)
>>> Xinds = array([1,2,3])
>>> Yinds = array([1,2,3])
>>> a
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14],
[15, 16, 17, 18, 19],
[20, 21, 22, 23, 24]])
>>> a[ix_(Xinds, Yinds)]
array([[ 6, 7, 8],
[11, 12, 13],
[16, 17, 18]])
>>> a[ix_(Xinds+1, Yinds)]
array([[11, 12, 13],
[16, 17, 18],
[21, 22, 23]])
>>> Y2inds = array([1,3,4])
>>> a[ix_(Xinds, Y2inds)]
array([[ 6, 8, 9],
[11, 13, 14],
[16, 18, 19]])
>>> a[ix_(Xinds, Y2inds-1)]
array([[ 5, 7, 8],
[10, 12, 13],
[15, 17, 18]])
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