Как найти «базу» массива записей - PullRequest
0 голосов
/ 05 сентября 2018

Как определяется base для массивов записей? документы кажутся описывающими то же поведение, что и обычные массивы, но это не так. Вот простой массив и массив записей, созданный из него.

>>> arr = np.zeros(10, dtype=[('a', float), ('b', int), ('c', int)])
>>> rec = arr.view(np.recarray)

База массива записей установлена ​​правильно

>>> arr is rec
False

>>> arr is rec.base
True

base правильно установлено для доступа к полям регулярного массива.

>>> arr['a'].base is arr
True

Однако для массива записей я не могу определить, что является основой. Это не обычный массив, массив записей, None или что-либо еще, что я пробовал.

>>> rec['a'].base is arr
False

>>> rec['a'].base is rec
False

>>> rec['a'].base is None
False

>>> rec['a'].base is rec['a']
False

>>> rec['a'].base is rec['a'].base
False

>>> f = rec['a']
>>> f.base is f
False

Он ведет себя так, как и ожидалось для индексации срезов

>>> arr[:3].base is arr
True

>>> rec[:3].base is rec
True

И он определенно все еще указывает на ту же память

>>> arr[0]
(0., 0, 0)

>>> rec['a'] = 1

>>> arr[0]
(1., 0, 0)

Итак, как найти фактическую базу массива записей?

1 Ответ

0 голосов
/ 05 сентября 2018

Фактическая база по-прежнему является атрибутом base. Если вы хотите рекурсивно следовать цепочке base, продолжайте:

def recursive_base(arr):
    while arr.base is not None:
        arr = arr.base
    return arr

Если вы хотите понять, почему rec['a'].base is not rec, взгляните на recarray.__getitem__:

def __getitem__(self, indx):
    obj = super(recarray, self).__getitem__(indx)

    # copy behavior of getattr, except that here
    # we might also be returning a single element
    if isinstance(obj, ndarray):
        if obj.dtype.fields:
            obj = obj.view(type(self))
            if issubclass(obj.dtype.type, nt.void):
                return obj.view(dtype=(self.dtype.type, obj.dtype))
            return obj
        else:
            return obj.view(type=ndarray)
    else:
        # return a single element
        return obj

В вашем случае возвращаемый объект - это представление результата, возвращаемого ndarray.__getitem__, а base - это объект, возвращаемый ndarray.__getitem__. Однако, как правило, не гарантируется, будет ли NumPy выравнивать цепочку base при установке нового массива base.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...