如何确定记录数组的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)
那么,如何找到记录数组的实际基础?
答案 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__
返回的结果的视图,而base
是ndarray.__getitem__
返回的对象。通常,尽管如此,不能保证在设置新数组的base
时NumPy是否会展平base
链。