如何找到记录数组的“基”
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__
返回的结果的视图,而 base
是 ndarray.__getitem__
返回的对象。但是,一般来说,在设置新数组的 base
.
时,不能保证 NumPy 是否会展平 base
链
记录数组的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__
返回的结果的视图,而 base
是 ndarray.__getitem__
返回的对象。但是,一般来说,在设置新数组的 base
.
base
链