0

How is base determined for record arrays? The docs seem to describe the same behavior as regular arrays, but that's not what it is. Here's a simple array, and a record array created from it.

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

The base of the record array is correctly set

>>> arr is rec
False

>>> arr is rec.base
True

The base is correctly set for field accesses of the regular array.

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

However, for the record array I can't determine what the base is. It's not the regular array, the record array, None, or anything else that I've tried.

>>> 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

It behaves as expected for indexing slices

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

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

And it definitely still points to the same memory

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

>>> rec['a'] = 1

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

So, how can the actual base of a record array be found?

4

1 回答 1

1

“实际基础”仍然是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__。不过,一般来说,不能保证 NumPybase在设置新数组的base.

于 2018-09-05T16:59:15.057 回答