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

时间:2018-09-05 16:48:11

标签: python arrays numpy recarray structured-array

如何确定记录数组的basedocs 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)

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

1 个答案:

答案 0 :(得分: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__返回的结果的视图,而basendarray.__getitem__返回的对象。通常,尽管如此,不能保证在设置新数组的base时NumPy是否会展平base链。