np.append
是一个简单的封面np.concatenate
def append(arr, values, axis=None):
arr = asanyarray(arr)
if axis is None:
if arr.ndim != 1:
arr = arr.ravel()
values = ravel(values)
axis = arr.ndim-1
return concatenate((arr, values), axis=axis)
In [89]: dt = np.dtype('U5,int')
In [90]: arr = np.array([('one',1)], dtype=dt)
In [91]: np.append(arr, ('two',2))
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-91-bc17d9ad4a77> in <module>()
----> 1 np.append(arr, ('two',2))
...
-> 5166 return concatenate((arr, values), axis=axis)
TypeError: invalid type promotion
在这种情况下它确实
In [92]: np.ravel(('two',2))
Out[92]: array(['two', '2'], dtype='<U3')
将元组转换为 2 元素字符串 dtype 数组。现在concatenate
尝试加入一个数组dt
与U3
数组,但不能。里面什么都没有append
使用arr.dtype
作为车削的基础values
到一个数组中。你需要自己做。numpy
只能做这么多来推断你的意图。 :)
因此,如果您指定 common dtype 它就可以工作:
In [93]: np.append(arr, np.array(('two',2),dt))
Out[93]: array([('one', 1), ('two', 2)], dtype=[('f0', '<U5'), ('f1', '<i4')])
我不喜欢append
因为新用户经常误用它。通常他们将其视为列表追加克隆,但事实并非如此。
但它确实有一个优点 - 它提高了 0d 输入的维度:
In [94]: np.concatenate([arr, np.array(('two',2),dt)])
...
ValueError: all the input arrays must have same number of dimensions
使第二个数组 1d 有效:
In [95]: np.concatenate([arr, np.array([('two',2)],dt)])
Out[95]: array([('one', 1), ('two', 2)], dtype=[('f0', '<U5'), ('f1', '<i4')])
append
隐藏尺寸调整concatenate
needs.
但如果可能的话,最好创建一个数组(或元组)列表并执行concatenate
就一次:
In [96]: alist = [('one',1),('two',2),('three',3)]
In [97]: ll = [np.array([x],dt) for x in alist]
In [98]: ll
Out[98]:
[array([('one', 1)], dtype=[('f0', '<U5'), ('f1', '<i4')]),
array([('two', 2)], dtype=[('f0', '<U5'), ('f1', '<i4')]),
array([('three', 3)], dtype=[('f0', '<U5'), ('f1', '<i4')])]
In [100]: np.concatenate(ll)
Out[100]:
array([('one', 1), ('two', 2), ('three', 3)],
dtype=[('f0', '<U5'), ('f1', '<i4')])
但是直接从元组列表创建数组更好:
In [101]: np.array(alist, dt)
Out[101]:
array([('one', 1), ('two', 2), ('three', 3)],
dtype=[('f0', '<U5'), ('f1', '<i4')])