有没有办法确定numpy数组是否是记录/结构数组?

时间:2014-07-17 22:30:57

标签: python arrays 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 个答案:

答案 0 :(得分:2)

这些都不是记录数组。根据{{​​3}}上的文档:

>>> 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之间没有基本的类型差异,它们都是ndarray。

答案 1 :(得分:0)

当我们从磁盘加载时,记录数组始终为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))  

答案 2 :(得分:0)

由于metaperture的答案说明了如何区分numpy数组是记录数组,还是不是结构化数组,here's what I found in the docs

对于非结构化数组,namesfields属性都将等于None。推荐的测试dtype是否结构化的方法是使用如果dt.names不是None 而不是如果dt.names 来说明具有0字段的dtype。

在您的示例中,

>> 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类型也是如此,但是我没有过多地尝试这些类型。