append_fields()
确实要求两个数组具有相同的形状。话虽这么说,正如您意识到的那样my_structured_array
,numpy 确实支持子数组(即字段本身可以是具有形状的数组)。
就你而言,我想你可能想要my_new_field
不是二维数组,而是一维数组(形状shape(my_structured_array)
) 具有 dtype 的元素,例如,dtype([('myfield', '<i8', (2,))])
。例如,
import numpy as np
from numpy.lib.recfunctions import append_fields
my_structured_array = np.array(
zip([0,1,2,3],[[4.3,3.2],[1.4,5.6],[6.,2.5],[4.5,5.4]]),
dtype=[('id','int8'),('pos','2float16')]
)
my_new_field = np.ones(
len(my_structured_array),
dtype=[('myfield', 'i8', 2)]
)
my_appended_array = append_fields(
my_structured_array,
'new',
data=my_new_field
)
将会产生,
>>> my_appended_array[0]
(0, [4.30078125, 3.19921875], ([1, 1],))
虽然数据类型稍微不方便,因为myfield
嵌套在new
,
>>> my_appended_array.dtype
dtype([('id', '|i1'), ('pos', '<f2', (2,)), ('new', [('myfield', '<i8', (2,))])])
然而,这很容易被强制消除,
>>> np.asarray(my_appended_array, dtype=[('id', '|i1'), ('pos', '<f2', (2,)), ('myfield', '<i8', (2,))])
array([(0, [4.30078125, 3.19921875], [0, 0]),
(1, [1.400390625, 5.6015625], [0, 0]), (2, [6.0, 2.5], [0, 0]),
(3, [4.5, 5.3984375], [0, 0])],
dtype=[('id', '|i1'), ('pos', '<f2', (2,)), ('myfield', '<i8', (2,))])
不过,有点不幸的是我们不得不重复 dtypemy_structured_array
这里。虽然乍一看似乎是numpy.lib.recfunctions.flatten_descr
可以做展平 dtype 的肮脏工作,不幸的是它给出了一个元组而不是所需的列表np.dtype
。然而,将其输出强制到列表可以解决这个问题,
>>> np.dtype(list(np.lib.recfunctions.flatten_descr(my_appended_array.dtype)))
dtype([('id', '|i1'), ('pos', '<f2', (2,)), ('myfield', '<i8', (2,))])
这可以作为 dtype 传递给np.asarray
,使事情对变化稍微更加稳健my_structured_array.dtype
.
事实上,像这样的微小不一致使得记录数组的处理变得混乱。人们会感觉事物可以更连贯地组合在一起。
Edit:事实证明,np.lib.recfunctions.merge_arrays
函数更适合这种合并,
>>> my_appended_array = merge_arrays([my_structured_array, my_new_field], flatten=True)
array([(0, [4.30078125, 3.19921875], [1, 1]),
(1, [1.400390625, 5.6015625], [1, 1]), (2, [6.0, 2.5], [1, 1]),
(3, [4.5, 5.3984375], [1, 1])],
dtype=[('id', '|i1'), ('pos', '<f2', (2,)), ('myfield', '<i8', (2,))])