有没有办法判断numpy数组是否为记录/结构数组?

10 投票
3 回答
2384 浏览
提问于 2025-04-18 13:46

我找不到任何方法来判断一个数组是否是记录数组:

>>> import numpy as npy
>>> c0=npy.array([1,2])
>>> c=c0.view(dtype=[('x',int),('y',int)])
>>> c
array([(1, 2)], 
      dtype=[('x', '<i8'), ('y', '<i8')])

这个类型总是 numpy.ndarray

>>> type(c)
<type 'numpy.ndarray'>
>>> isinstance(c,npy.recarray)
False

元素类型总是 numpy.void

>>> type(c[0])
<type 'numpy.void'>

现在我使用 dtype.fields 来判断:

>>> def isRecarray(a):
    return a.dtype.fields != None

>>> isRecarray(c0)
False
>>> isRecarray(c)
True

有没有什么官方的方法可以判断一个数组是否是记录数组?

3 个回答

1

当我们从磁盘加载记录数组时,它总是一个 np.ndarray 类型的数组。但是为了自动将这些 np.ndarray 转换成 np.recarray 类型,我们还需要一个叫 isRecarray 的函数。

所以在从磁盘加载数据时,如果我们想把任何 numpy 的记录变成 recarray,我们需要一些工具。我猜 dtype.isbuiltin 在这种情况下会更有用。

x = np.array([(1.0, 2), (3.0, 4)], dtype=[('x', float), ('y', int)])
x_rec = x.view(np.recarray)
np.save("x_rec.npy", x_rec)
x_rec_from_disk = np.load("x_rec.npy")

# still prints np.ndarray as recarray info is not saved
print(type(x_rec_from_disk))  

# so solution can be to rely on dtype.isbuiltin
if not x_rec_from_disk.dtype.isbuiltin:
    x_rec_from_disk = x_rec_from_disk.view(np.recarray)

# will print np.recarray
print(type(x_rec_from_disk))  
4

因为metaperture的回答解释了如何区分一个numpy数组是记录数组而不是结构化数组,所以我在文档中找到的内容是这样的

对于非结构化数组,namesfields这两个属性的值都会是None。检查一个数据类型是否是结构化的推荐方法是用if dt.names is not None,而不是if dt.names,这样可以处理那些字段数为0的数据类型。

所以在你的例子中,

>> import numpy as npy
>> c0=npy.array([1,2])
>> c=c0.view(dtype=[('x',int),('y',int)])
>> c
array([(1, 2)], dtype=[('x', '<i8'), ('y', '<i8')])

你是对的,

>> type(c) == type(c0)
True

但是

>> c0.dtype.names
>> c0.dtype.names is None
True
>> c.dtype.names
('x', 'y')
>> c.dtype.names is None
False

这让你能看到c是一个结构化数组,而c0不是!这同样适用于np.recarray类型,不过我还没有太多尝试过这些。

2

这两者都不是记录数组。根据文档的说明:

>>> x = np.array([(1.0, 2), (3.0, 4)], dtype=[('x', float), ('y', int)])
>>> y = x.view(np.recarray)
>>> type(x), type(y)
(<type 'numpy.ndarray'>, <class 'numpy.core.records.recarray'>)

ndarray.view 是用来创建一个新的引用,指向同一块内存,同时也给字段命名。你的 c0c 之间没有根本的类型区别,它们都是 ndarrays。

撰写回答