I am working on code conversion from IDL to python and came across a hurdle. Some code I was given needs to be converted to python. In the IDL version, array element is accessed by int value rather than 3D index. Using the same technique, python gives an error. Any ideas how to resolve this?
Here is a snippet of IDL code for illustration purposes:
x = reform(indgen(100), 2, 5, 10)
help, x ;this results in Array[2,5,10]
x[-76] ; results in value 24
Here is a snippet of python code for illustration purposes
import numpy as np
x=np.arange(100).reshape(2,5,10)
x.shape #this results in (2,5,10)
x[-76]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: index -76 is out of bounds for axis 0 with size 2
NumPy arrays (or anything indexed with integers in Python) doesn't just support that flattened type of indexing. For one, it assumes we know in what order the dimensions are kept in memory, which can be risky.
However, NumPy does include some functions and methods to help with this:
import numpy as np
x = np.arange(100).reshape(2, 5, 10)
# to just get the value at that IDL index
print(x.flat[-76])
def idl_idx(xs: np.ndarray, idx: int):
# unravel_index doesn't support negative indices, so convert them
if idx < 0:
idx = xs.size + idx
return np.unravel_index(idx, xs.shape)
# to get the index as a tuple
print(idl_idx(x, -76))
# to just get that value normally
print(x[0, 2, 4])
Output:
24
(0, 2, 4)
24
There's no way to change the np.ndarray
type itself to support this behaviour, although you could subclass it and add this behaviour. But that would have the limitation of only working for arrays of that type, while some functions (in NumPy and elsewhere) may return new arrays of type np.ndarray
that would no longer work like that - that may be something you want to avoid.