任何熟悉Python的人都会知道列表追加的方法。
a = [1, 2, 3]
a.append(4)
print(a)
# Expected result
# [1, 2, 3, 4]
但是如果你想追加到一个NumPy数组上呢?在这种情况下,你有几个选择。在NumPy的习惯性代码中,你最常看到的是 [np.concatenate()](https://numpy.org/doc/stable/reference/generated/numpy.concatenate.html)操作,它将两个或更多的数组沿给定的轴连接起来。
NumPy确实有一个np.append() 操作,你可以用它来代替,但是你必须要小心一点,因为这个API里面有一些奇怪的东西。
对于一维数组,np.append() 的工作方式与你所期望的一样 (与 Python 列表相同)。
np.append(np.zeros(3), 1)
# Expected result
# array([0., 0., 0., 1.])
你不能把.append() 作为ndarray 的一个方法,但是你可以把一个单一的值粘到一个向量的末端。当你试图追加 N-D 数组时,它就变得很奇怪了。
看看这个。让我们从一个3×3的身份矩阵开始,Python和NumPy都有。
x = np.eye(3)
print(x)
# Expected result
# [[1. 0. 0.]
# [0. 1. 0.]
# [0. 0. 1.]]
python_x = x.astype(int).tolist()
print(python_x)
# Expected result
# [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
到目前为止还不错。在数组被打印到屏幕上的方式和数值的底层数据类型方面存在差异,但基本上x 和python_x 有相同的数据。
现在把相同的数据附加到它们每个人身上。
python_x.append([1, 0, 0])
print(python_x)
# Expected result
# [[1, 0, 0], [0, 1, 0], [0, 0, 1], [1, 0, 0]]
np.append(x, [1, 0, 0])
# Expected result
# array([1., 0., 0., 0., 1., 0., 0., 0., 1., 1., 0., 0.])
注意。Python的list append给矩阵增加了一行,而NumPy则将原始数组压平,并将压平后的数组附加到它上面,留给我们的是一个与输入不同等级的数组。
这种行为在np.append() 文档中被清楚地阐述了,但是如果你期望用标准的Python方法来工作,那就很奇怪了。如果你想在NumPy中向一个二维数组追加一行,你需要1)确保追加的值有相同的维数,2)指定轴。
np.append(x, [[1, 0, 0]], axis=0)
# Expected result
# array([[1., 0., 0.],
# [0., 1., 0.],
# [0., 0., 1.],
# [1., 0., 0.]])
或者你可以像其他人一样直接使用np.concatenate() 。
np.concatenate([x, [[1, 0, 0]]])
# Expected result
# array([[1., 0., 0.],
# [0., 1., 0.],
# [0., 0., 1.],
# [1., 0., 0.]])
你仍然要在所有的输入中匹配维数,但这种行为不太可能让你的代码的未来读者感到惊讶。