如何找到记录数组的“基”

How to find the `base` of a record array

记录数组的base是如何确定的? docs seem 描述与常规数组相同的行为,但事实并非如此。 这是一个简单的数组,以及一个从中创建的记录数组。

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

那么,如何找到记录数组的实际基数呢?

"actual base" 仍然是 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__ 返回的结果的视图,而 basendarray.__getitem__ 返回的对象。但是,一般来说,在设置新数组的 base.

时,不能保证 NumPy 是否会展平 base