NumPy的追加操作是如何进行的

100 阅读2分钟

任何熟悉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]]

到目前为止还不错。在数组被打印到屏幕上的方式和数值的底层数据类型方面存在差异,但基本上xpython_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.]])

你仍然要在所有的输入中匹配维数,但这种行为不太可能让你的代码的未来读者感到惊讶。