在 numpy 中合并数组比较常用的方法有 concatenate、vstack 和 hstack。在介绍这三个方法之前,首先创建几个不同维度的数组:
代码语言:javascript复制import numpy as np
# 创建一维数组
x = np.array([1, 2, 3])
y = np.array([3, 2, 1])
z = np.array([666, 666, 666])
# 创建二维数组
A = np.array([[1, 2, 3],
[4, 5, 6]])
B = np.array([[100, 200, 300],
[400, 500, 600]])
concatenate
numpy.concatenate((a1, a2, ...), axis = 0)
其中:
- a1, a2,....: 待合并的数组
- axis: 沿着数组合并的维度,默认为 0(对于二维数组来说,默认沿着行的方向进行合并)
这里需要注意 a1, a2,... 待合并的数组除了待合并的维度,其余维度上的值必须相等。二维数组(矩阵)有两个 axis,一个 axis = 0(行方向),一个 axis = 1(列方向),如果是多维数组依次类推。比如:
- 形状为 (2, 3) 和 (1, 3) 的两个二维数组可以沿着 axis = 0 的方向进行合并,合并的结果为 (3, 3);
- 形状为 (2, 3) 和 (2, 3) 的两个二维数组既可以沿着 axis = 0 的方向也可以沿着 axis = 1 的方向合并;
- 形状为 (2, 1) 和 (1, 3) 的两个二维数组既不可以沿着 axis = 0 的方向也可以沿着 axis = 1 的方向合并;
合并多个一维数组:
代码语言:javascript复制print(np.concatenate((x, y)))
'''
array([1, 2, 3, 3, 2, 1])
'''
print(np.concatenate((x, y, z)))
'''
array([ 1, 2, 3, 3, 2, 1, 666, 666, 666])
'''
合并多个二维数组:
代码语言:javascript复制print(np.concatenate((A, B), axis = 0))
'''
array([[ 1, 2, 3],
[ 4, 5, 6],
[100, 200, 300],
[400, 500, 600]])
'''
axis = 0,即沿着行方向进行合并。这种合并二维数组的场景非常多,比如对于输入特征为二维数组的情况下,需要补充新的样本,可以将二维数组沿着行方向进行合并,有时会将行称为样本维度。
代码语言:javascript复制print(np.concatenate((A, B), axis = 1))
'''
array([[ 1, 2, 3, 100, 200, 300],
[ 4, 5, 6, 400, 500, 600]])
'''
axis = 1,即沿着列方向进行合并。比如对于输入特征为二维数组的情况下,需要为输入补充一些新的特征,可以将二维数组沿着列方向进行合并,有时会将列称为特征维度。
待合并的数组必须拥有相同的维度,如果不同维度则会抛出 ValueError 异常。
代码语言:javascript复制print(np.concatenate([A, z]))
'''
ValueError: all the input arrays must have same number of dimensions, but the array at index 0 has 2 dimension(s) and the array at index 1 has 1 dimension(s)
'''
这是因为 A 的形状为 (2, 3),而 z 的形状为 (3,),如果想要让两个数组进行合并,可以将 z 的形状转换为 (1, 3),这样我们就可以沿着 axis = 0 的方向进行合并。
代码语言:javascript复制print(np.concatenate([A, z.reshape(1, -1)]))
'''
array([[ 1, 2, 3],
[ 4, 5, 6],
[666, 666, 666]])
'''
需要注意拼接后的结果是一个新的数组。
vstack 和 hstack
我们在实际开发中,比较常用的操作就是对二维或者三维数组进行行和列的合并操作,所以 numpy 为我们提供了更加方便的 vstack 和 hstack。vstack 将数组沿着行的方向进行合并操作,而 hstack 将数组沿着列的方向进行合并操作。
代码语言:javascript复制print(np.vstack((A, B)))
'''
array([[ 1, 2, 3],
[ 4, 5, 6],
[100, 200, 300],
[400, 500, 600]])
'''
print(np.hstack((A, B)))
'''
array([[ 1, 2, 3, 100, 200, 300],
[ 4, 5, 6, 400, 500, 600]])
'''
上面的操作我们同样可以使用 concatenate 实现,换句话说 vstack 和 hstack 是 concatenate 更为具体的操作。
不过需要注意,当处理一维数组时:
- vstack 会把形状为 (N, ) 的一维数组转换为 (1, N) 的二维数组,然后进行后续的合并操作
- hstack 的处理方式和 concatenate 一样,二维数组和一维数组合并会抛出ValueError 异常,而两个一维数组合并会合并成新的一维数组,比如合并形状分别为 (3, ) 和 (2, ) 的两个一维数组,合并的结果为形状为 (5, ) 的一维数组。
print(np.vstack((x,y)))
'''
array([[1, 2, 3],
[3, 2, 1]])
'''
print(np.vstack((A, z)))
'''
array([[ 1, 2, 3],
[ 4, 5, 6],
[666, 666, 666]])
'''
使用 vstack 沿着行方向合并 A 和 z 两个数组,没有抛出异常,这是因为 vstack 会将一维数组转换为二维数组。
针对一维数组,hstack 的处理方式和 concatenate 一样。
代码语言:javascript复制print(np.hstack((x, y)))
'''
array([1, 2, 3, 3, 2, 1])
'''
print(np.hstack((A, z)))
'''
ValueError: all the input arrays must have same number of dimensions, but the array at index 0 has 2 dimension(s) and the array at index 1 has 1 dimension(s)
'''