将数据列添加到只有一行的 numpy rec 数组
Adding a data column to a numpy rec array with only one row
我需要向 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')]))
创建初始数组,使其形状为 (1,);注意额外的括号:
In [17]: x = np.rec.array([[1, 2, 3]])
(如果 x
是您无法通过这种方式控制的输入,您可以在 append_fields()
中使用它之前使用 x = np.atleast_1d(x)
。)
然后确保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')])
这是一种无需重新函数即可完成工作的方法:
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
代码中看到的情况来看,我认为它同样快。当然对于单行速度不是问题。通常,这些函数会创建一个具有目标数据类型的新 'blank' 数组,并按名称(可能递归地)将字段从源复制到目标。通常一个数组的记录比字段多很多,所以字段上的迭代相对来说并不慢。
我需要向 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')]))
创建初始数组,使其形状为 (1,);注意额外的括号:
In [17]: x = np.rec.array([[1, 2, 3]])
(如果 x
是您无法通过这种方式控制的输入,您可以在 append_fields()
中使用它之前使用 x = np.atleast_1d(x)
。)
然后确保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')])
这是一种无需重新函数即可完成工作的方法:
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
代码中看到的情况来看,我认为它同样快。当然对于单行速度不是问题。通常,这些函数会创建一个具有目标数据类型的新 'blank' 数组,并按名称(可能递归地)将字段从源复制到目标。通常一个数组的记录比字段多很多,所以字段上的迭代相对来说并不慢。