NumPy数据类型错误 - (结构化数组创建)

3

我有些困惑,不明白为什么下面的代码无法正常运行:

np.dtype(dict(names="10", formats=np.float64))

我一直在努力解决这个问题,因为我想让numpy中的recfunctions函数正常工作,但由于numpy.dtype存在问题,我一直没有成功。目前我收到了以下错误信息:

dtype = np.dtype(dict(names=names, formats=formats))
ValueError: all items in the dictionary must have the same length.

我希望获得一种数据结构,该结构将包含一个记录数组类型,并在每个分配字段内包含多列数据 - 类似于字典,其中每个值都是2D数组或多列数据。通常情况下,每个键或记录的数据可能最终为大约6列,2000行,共有约200个记录。

以下是我在完整脚本中尝试过的方法:(尽管仍然会产生相同的错误)

import numpy as np
from numpy.lib import recfunctions


# Just function to make random data
def make_data(i, j):
    # some arbitrary function to show that the number of columns may change, but rows stay the same length
    if i%3==0:
        data = np.array([[i for i in range(0,1150)]*t for t in range(0,3)])
    else:
        data = np.array([[i for i in range(0,1150)]*t for t in range(0,6)])
    return data

def data_struct(low_ij, high_ij):

    """
    Data Structure to contain several columns of data for different combined values between "low ij" and "high ij"

    Key: "(i, j)"
    Value: numpy ndarray (multidimensional)
    """

    for i in range(0,low_ij+1):
        for j in range(0,high_ij+1):
            # Get rid of some of the combinations
            # (unimportant)
            if(i<low_ij and j<low_ij):
                break
            elif(i<j):
                break

            # Combinations of interest to create structure
            else:
                names = str(i)+str(j)
                formats = np.float64
                data = np.array(make_data(i, j))
                try:
                    data_struct = recfunctions.append_fields(base=data_struct, names=names, data=data, dtypes=formats)
                # First loop will assign data_struct using this exception,
                # then proceed to use the try statement to add on the rest of the data
                except UnboundLocalError:
                    dtype = np.dtype(dict(names=names, formats=formats))
                    data_struct = np.array(data, dtype=dtype)

    return data_struct
2个回答

1

您需要传递一个值列表和一个格式列表,而不是单个值和单个格式。如果您调试问题,您会发现

type(names)   # result is <type 'str'>
type(formats) # result is <type 'type'>

然后发生的是,dict被初始化为

{'formats': numpy.float64, 'names': '30'}

每个formatsnames都应该是一个列表。

另外,注意formats应该是一个字符串列表,例如['float64','u8']等。


1

看起来你正在尝试构建一个类似于结构化数组的东西:

In [152]: names=['1','2','3','4']
In [153]: formats=[(float,2),(float,3),(float,2),(float,3)]
In [154]: dt=np.dtype({'names':names, 'formats':formats})
In [156]: ds=np.zeros(5, dtype=dt)

In [157]: ds
Out[157]: 
array([([0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0], [0.0, 0.0, 0.0]),
       ([0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0], [0.0, 0.0, 0.0]),
       ([0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0], [0.0, 0.0, 0.0]),
       ([0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0], [0.0, 0.0, 0.0]),
       ([0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0], [0.0, 0.0, 0.0])], 
      dtype=[('1', '<f8', (2,)), ('2', '<f8', (3,)), ('3', '<f8', (2,)), 
           ('4', '<f8', (3,))])
In [159]: ds['1']=np.arange(10).reshape(5,2)
In [160]: ds['2']=np.arange(15).reshape(5,3)

换句话说,多个字段,每个字段都有不同数量的“列”(形状)。
在这里,我创建并初始化整个数组,然后逐个填充字段。这似乎是创建复杂结构化数组最直接的方式。
您正在尝试逐步构建这样的数组,从一个字段开始,并使用recfunctions.append_fields添加新字段。
In [162]: i=1; 
   ds2 = np.array(np.arange(5),dtype=np.dtype({'names':[str(i)],'formats':[float]}))
In [164]: i+=1;
   ds2=recfunctions.append_fields(base=ds2,names=str(i),dtypes=float,
      data=np.arange(5), usemask=False,asrecarray=False)
In [165]: i+=1;
   ds2=recfunctions.append_fields(base=ds2,names=str(i),dtypes=float,
      data=np.arange(5), usemask=False,asrecarray=False)

In [166]: ds2
Out[166]: 
array(data = [(0.0, 0.0, 0.0) (1.0, 1.0, 1.0) (2.0, 2.0, 2.0) 
    (3.0, 3.0, 3.0) (4.0, 4.0, 4.0)], 
    dtype = [('1', '<f8'), ('2', '<f8'), ('3', '<f8')])

这在附加字段都只有1个“列”的情况下有效。通过掩码,它们甚至可以具有不同数量的“行”。但是,当我尝试改变内部形状时,它会出现附加字段的问题。即使我们可以让增量recfunctions方法工作,它可能比初始化和填充方法更慢。即使您不知道每个字段的形状,也可以将它们全部收集到字典中,并从中组装数组。这种结构化数组与字典一样紧凑或高效,只是使某些数据访问风格(跨字段)更方便。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接