1

我需要将一列数据添加到 numpy rec 数组中。我在这里看到了很多答案,但它们似乎不适用于只包含一行的 rec 数组......

假设我有一个 rec 数组x

>>> x = np.rec.array([1, 2, 3])
>>> print(x)
rec.array((1, 2, 3), 
      dtype=[('f0', '<i8'), ('f1', '<i8'), ('f2', '<i8')])

我想将该值附加4到具有自己的字段名称和数据类型的新列中,例如

 rec.array((1, 2, 3, 4), 
      dtype=[('f0', '<i8'), ('f1', '<i8'), ('f2', '<i8'), ('f3', '<i8')])

如果我尝试使用正常append_fields方法添加一列;

>>> np.lib.recfunctions.append_fields(x, 'f3', 4, dtypes='<i8', 
usemask=False, asrecarray=True)

然后我最终得到

TypeError: len() of unsized object

事实证明,对于只有一行的 rec 数组,len(x)不起作用,而x.size确实起作用。如果我改为使用np.hstack(),我会得到TypeError: invalid type promotion,如果我尝试np.c_,我会得到不想要的结果

>>> np.c_[x, 4]
array([[(1, 2, 3), (4, 4, 4)]], 
  dtype=(numpy.record, [('f0', '<i8'), ('f1', '<i8'), ('f2', '<i8')]))
4

2 回答 2

2

创建初始数组,使其具有形状 (1,); 注意额外的括号:

In [17]: x = np.rec.array([[1, 2, 3]])

(如果x是您无法以这种方式控制的输入,您可以x = np.atleast_1d(x)在使用它之前使用它append_fields()。)

然后确保给出的值append_fields也是长度为 1 的序列:

In [18]: np.lib.recfunctions.append_fields(x, 'f3', [4], dtypes='<i8', 
    ...: usemask=False, asrecarray=True)
Out[18]: 
rec.array([(1, 2, 3, 4)], 
          dtype=[('f0', '<i8'), ('f1', '<i8'), ('f2', '<i8'), ('f3', '<i8')])
于 2017-05-18T18:27:25.670 回答
1

这是一种无需recfunctions即可完成工作的方法:

In [64]: x = np.rec.array((1, 2, 3))
In [65]: y=np.zeros(x.shape, dtype=x.dtype.descr+[('f3','<i4')])
In [66]: y
Out[66]: 
array((0, 0, 0, 0), 
      dtype=[('f0', '<i4'), ('f1', '<i4'), ('f2', '<i4'), ('f3', '<i4')])
In [67]: for name in x.dtype.names: y[name] = x[name]
In [68]: y['f3']=4
In [69]: y
Out[69]: 
array((1, 2, 3, 4), 
      dtype=[('f0', '<i4'), ('f1', '<i4'), ('f2', '<i4'), ('f3', '<i4')])

从我在recfunctions代码中看到的情况来看,我认为它同样快。当然对于单行速度不是问题。通常,这些函数使用目标 dtype 创建一个新的“空白”数组,并按名称(可能递归地)从源复制字段到目标。通常数组的记录比字段多得多,因此相对而言,字段的迭代并不慢。

于 2017-05-18T18:45:28.123 回答