有没有办法判断numpy数组是否为记录/结构数组?
我找不到任何方法来判断一个数组是否是记录数组:
>>> 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数组是记录数组而不是结构化数组,所以我在文档中找到的内容是这样的:
对于非结构化数组,
names
和fields
这两个属性的值都会是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
是用来创建一个新的引用,指向同一块内存,同时也给字段命名。你的 c0
和 c
之间没有根本的类型区别,它们都是 ndarrays。