pin_drop当前位置:知识文库 ❯ 图文
NumPy数组拼接与分割 - concatenate/stack/split
一、概述
NumPy提供了多种数组拼接和分割方法。拼接(concatenate/stack/vstack/hstack)将多个数组合并为一个;分割(split/array_split/vsplit/hsplit)将一个数组拆分为多个。这些操作在数据预处理、特征工程和批量处理中非常常用。
理解不同函数的区别非常重要:concatenate沿已有轴拼接,不增加维度;stack沿新轴堆叠,会增加一个维度;split要求等分必须整除,array_split支持不等分。
二、语法与常用函数
代码示例
# 拼接
np.concatenate((a1, a2), axis=0)
np.stack((a1, a2), axis=0)
np.vstack((a1, a2))
np.hstack((a1, a2))
np.dstack((a1, a2))
# 分割
np.split(arr, indices, axis=0)
np.array_split(arr, n, axis=0)
np.vsplit(arr, indices)
np.hsplit(arr, indices)三、参数说明
拼接函数
分割函数
四、数组拼接
vstack()将数组垂直(上下)拼接,等价于concatenate(axis=0)。hstack()将数组水平(左右)拼接,等价于concatenate(axis=1)。
代码示例
import numpy as np
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])
print(f"数组a:\n{a}")
print(f"数组b:\n{b}")
# 垂直拼接(上下)
print(f"\nvstack:\n{np.vstack((a, b))}")
# 水平拼接(左右)
print(f"\nhstack:\n{np.hstack((a, b))}")
# concatenate指定轴
print(f"\nconcatenate axis=0:\n{np.concatenate((a, b), axis=0)}")
print(f"concatenate axis=1:\n{np.concatenate((a, b), axis=1)}")输出结果:
代码示例
数组a:
[[1 2]
[3 4]]
数组b:
[[5 6]
[7 8]]
vstack:
[[1 2]
[3 4]
[5 6]
[7 8]]
hstack:
[[1 2 5 6]
[3 4 7 8]]
concatenate axis=0:
[[1 2]
[3 4]
[5 6]
[7 8]]
concatenate axis=1:
[[1 2 5 6]
[3 4 7 8]]五、stack与一维数组拼接
stack()沿新轴堆叠数组,会增加一个维度。axis=0表示新轴在最前面,axis=1表示新轴在第二位。对于一维数组,vstack将其作为行拼接(生成2D),hstack将其首尾相连(仍是1D)。
代码示例
import numpy as np
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
# stack:沿新轴堆叠
print(f"stack axis=0:\n{np.stack((a, b), axis=0)}")
print(f"stack axis=1:\n{np.stack((a, b), axis=1)}")
# 一维数组的vstack和hstack
print(f"\nvstack:\n{np.vstack((a, b))}")
print(f"hstack: {np.hstack((a, b))}")
# column_stack:将一维数组作为列拼接
c = np.array([10, 20, 30])
d = np.array([40, 50, 60])
print(f"\ncolumn_stack:\n{np.column_stack((c, d))}")输出结果:
代码示例
stack axis=0:
[[1 2 3]
[4 5 6]]
stack axis=1:
[[1 4]
[2 5]
[3 6]]
vstack: [[1 2 3]
[4 5 6]]
hstack: [1 2 3 4 5 6]
column_stack:
[[10 40]
[20 50]
[30 60]]小贴士
column_stack是hstack的便捷写法,专门用于将一维数组按列拼接为二维数组。它会自动将一维数组reshape为(n,1)后再进行hstack。在处理特征列时非常实用。
六、数组分割
split()要求分割必须整除,否则会抛出ValueError。array_split()可以处理不等分情况,多余元素会分配到前面的份中。hsplit()和vsplit()分别是沿axis=1和axis=0的便捷分割。
代码示例
import numpy as np
arr = np.arange(12).reshape(3, 4)
print(f"原数组:\n{arr}")
# 水平分割(按列)
h_parts = np.hsplit(arr, 2)
print(f"\nhsplit为2份:")
for i, part in enumerate(h_parts):
print(f" 部分{i}:\n{part}")
# 垂直分割(按行)
v_parts = np.vsplit(arr, 3)
print(f"\nvsplit为3份:")
for i, part in enumerate(v_parts):
print(f" 部分{i}: {part}")
# split指定分割点
arr1d = np.arange(10)
parts = np.split(arr1d, [3, 7])
print(f"\nsplit([3,7]): {parts}")
# array_split:不等分
arr2 = np.arange(10)
parts2 = np.array_split(arr2, 3)
print(f"\narray_split为3份:")
for i, part in enumerate(parts2):
print(f" 部分{i}: {part}, 长度: {len(part)}")输出结果:
代码示例
原数组:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
hsplit为2份:
部分0:
[[0 1]
[4 5]
[8 9]]
部分1:
[[ 2 3]
[ 6 7]
[10 11]]
vsplit为3份:
部分0: [[0 1 2 3]]
部分1: [[4 5 6 7]]
部分2: [[ 8 9 10 11]]
split([3,7]): [array([0, 1, 2]), array([3, 4, 5, 6]), array([7, 8, 9])]
array_split为3份:
部分0: [0 1 2 3], 长度: 4
部分1: [4 5 6], 长度: 3
部分2: [7 8 9], 长度: 3七、实际应用场景
-
场景1:数据预处理中,使用hstack拼接特征列,vstack拼接样本行,构建完整的训练数据集
-
场景2:深度学习中,使用stack将多个样本堆叠为一个batch,用于模型训练
-
场景3:大数据处理中,使用array_split将数据分成多份并行处理,提升处理效率
八、注意事项
注意:concatenate要求非拼接轴的维度必须一致,否则报错。例如两个(2,3)和(2,4)的数组只能沿axis=1拼接。
注意:split要求等分必须整除,否则抛出ValueError;array_split可以不等分,自动将多余元素分配到前面的份中。
注意:stack会创建新维度,concatenate不会。stack要求所有输入数组shape完全一致。
九、拼接函数对比
十、练习题
练习1
创建两个2x3的数组,分别使用vstack和hstack拼接,打印结果和shape
练习2
创建三个一维数组,使用stack将它们堆叠为3xN的二维数组,分别沿axis=0和axis=1
练习3
创建一个6x6的数组,使用hsplit和vsplit将其分割为4个3x3的子数组
常见问题
concatenate和stack的核心区别是什么?
concatenate沿已有的轴拼接,不改变维度数;stack沿新轴堆叠,会增加一个维度。例如两个(2,3)数组,concatenate后可能是(4,3)或(2,6),stack后一定是(2,2,3)。
如何拼接维度不同的数组?
需要先将维度低的数组扩展到高维度,可以使用np.newaxis或reshape。例如一维数组a,使用a[np.newaxis, :]可变为二维(1,n),然后进行concatenate。
array_split不等分时的分配规则是什么?
当数组长度不能被份数整除时,前r份每份多一个元素(r=余数)。例如10个元素分3份,10÷3=3余1,则第1份有4个元素,第2、3份各3个。
vstack和hstack对一维数组的处理有何不同?
vstack将一维数组视为行向量,拼接后生成二维数组(n, m);hstack将一维数组视为元素序列,拼接后仍是一维数组(n+m)。这是初学者容易混淆的地方。
本文涉及AI创作
内容由AI创作,请仔细甄别