Accessing structured array scalars by index

It’s not making sense to me yet, but usually that’s because I’m a bit thick :slight_smile:

If I print the numba type, like

print(numba.from_dtype(arr.dtype))

returns

Record(f0[type=int32;offset=0],f1[type=float32;offset=4],f2[type=float32;offset=8];12;False)

Specifying the ‘f1’ literally seems to be addressing a different problem… that the value of member_idx is unknown at compile time. However, in that case I’d expect that a literal column number would be sufficient, like

@njit
def get_elem(arr, idx, member_idx):
    return arr[idx][1]

Since the member index is a literal, similar to your example with

def get_elem(arr, idx):
    return arr[idx]['f1']

I did (of course :slight_smile: ) try to look up the name from an index using your second example with a literal member index and received almost the same error as in the original posting. It’s quite possible my implementation had an error.

import numba
from numba import njit
import numpy as np
from numba.extending import overload

def names_tuple(val):
    if isinstance(val, np.dtype):
        val = numba.from_dtype(val)
        return tuple([name for name, field in val.fields.items()])
    if hasattr(val, 'dtype'):
        return names_tuple(val.dtype)
    raise RuntimeError(f"FIXME: I don't know how to handle type '{val}'")

def structured_name(array, member_idx):
    pass

@overload(structured_name)
def ol_structured_name(array, member_idx):
    names = names_tuple(array)
    print("names=", names)
    def _(array, member_idx):
        return names[member_idx]
    return _

arr = np.array([(1, 2., 3.)], dtype='i, f, f')
@njit
def get_elem(arr, idx, member_idx):
    return arr[0][structured_name(arr, 1)]

print(get_elem(arr, 0, 1))

output is

names= (‘f0’, ‘f1’, ‘f2’)
…snip…
numba.core.errors.TypingError: Failed in nopython mode pipeline (step: nopython frontend)
No implementation of function Function() found for signature:

getitem(Record(f0[type=int32;offset=0],f1[type=float32;offset=4],f2[type=float32;offset=8];12;False), unicode_type)

There are 22 candidate implementations:

  • Of which 22 did not match due to:
    Overload of function ‘getitem’: File: : Line N/A.
    With argument(s): ‘(Record(f0[type=int32;offset=0],f1[type=float32;offset=4],f2[type=float32;offset=8];12;False), unicode_type)’:
    No match.