4.2 数组的拼接与分割
NumPy数组拼接与分割全面教程:hstack、vstack、dstack、concatenate和split函数详解
本教程详细讲解NumPy中数组的拼接与分割操作,涵盖横向拼接(hstack和axis=1的concatenate)、纵向拼接(vstack和axis=0的concatenate)、深度拼接(dstack)及多维拼接,以及数组分割(split、hsplit、vsplit)。适合新手学习,配有代码示例和易懂解释。
NumPy数组的拼接与分割:入门到精通教程
引言
NumPy是Python中用于科学计算的核心库,提供了强大的多维数组操作功能。在数据分析、机器学习等领域,经常需要对数组进行拼接和分割来整理数据。本教程将详细介绍NumPy中数组的拼接和分割方法,从基础概念到高级应用,帮助新手轻松上手。
1. 数组拼接(Array Concatenation)
数组拼接是指将多个数组沿着指定轴组合成一个新数组。NumPy提供了多种函数来实现拼接,包括hstack、vstack、dstack和通用的np.concatenate。
1.1 横向拼接(Horizontal Stacking)
横向拼接是将数组沿水平方向(即列方向)拼接在一起。适用于两个或多个数组行数相同的情况。
使用hstack()
hstack()函数专门用于横向拼接,语法简单:np.hstack((array1, array2, ...))。
import numpy as np
# 示例:两个一维数组
arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])
result_hstack = np.hstack((arr1, arr2))
print("hstack拼接结果:", result_hstack)
# 输出: [1 2 3 4 5 6]
# 示例:两个二维数组
arr3 = np.array([[1, 2], [3, 4]])
arr4 = np.array([[5, 6], [7, 8]])
result_hstack_2d = np.hstack((arr3, arr4))
print("hstack拼接二维数组结果:")
print(result_hstack_2d)
# 输出:
# [[1 2 5 6]
# [3 4 7 8]]
解释:hstack将arr3和arr4按列拼接,要求行数相同。如果数组维度不同,会报错。
使用np.concatenate(axis=1)
np.concatenate是一个通用函数,可以通过指定axis参数来实现不同方向的拼接。axis=1表示沿列方向拼接,与hstack类似。
# 使用concatenate进行横向拼接
result_concatenate_h = np.concatenate((arr3, arr4), axis=1)
print("concatenate(axis=1)拼接结果:")
print(result_concatenate_h)
# 输出: 与hstack相同
注意:axis=1对应第二个轴(列),适用于二维或更高维数组。对于一维数组,axis=1可能不适用(因为一维数组只有一个轴)。
1.2 纵向拼接(Vertical Stacking)
纵向拼接是将数组沿垂直方向(即行方向)拼接在一起。适用于两个或多个数组列数相同的情况。
使用vstack()
vstack()函数专门用于纵向拼接:np.vstack((array1, array2, ...))。
# 示例:一维数组(会被视为行向量)
arr5 = np.array([1, 2, 3])
arr6 = np.array([4, 5, 6])
result_vstack = np.vstack((arr5, arr6))
print("vstack拼接一维数组结果:")
print(result_vstack)
# 输出:
# [[1 2 3]
# [4 5 6]]
# 示例:二维数组
arr7 = np.array([[1, 2], [3, 4]])
arr8 = np.array([[5, 6], [7, 8]])
result_vstack_2d = np.vstack((arr7, arr8))
print("vstack拼接二维数组结果:")
print(result_vstack_2d)
# 输出:
# [[1 2]
# [3 4]
# [5 6]
# [7 8]]
解释:vstack将数组按行拼接,要求列数相同。一维数组会被提升为行向量。
使用np.concatenate(axis=0)
axis=0表示沿行方向拼接,与vstack类似。
result_concatenate_v = np.concatenate((arr7, arr8), axis=0)
print("concatenate(axis=0)拼接结果:")
print(result_concatenate_v)
# 输出: 与vstack相同
注意:axis=0是默认值,因此np.concatenate((arr1, arr2))等同于axis=0的拼接。
1.3 深度拼接(Depth Stacking)
深度拼接用于将多个二维数组沿第三个轴(深度方向)拼接成三维数组。使用dstack()函数。
# 示例:两个二维数组
arr9 = np.array([[1, 2], [3, 4]])
arr10 = np.array([[5, 6], [7, 8]])
result_dstack = np.dstack((arr9, arr10))
print("dstack拼接结果:")
print(result_dstack)
print("形状:", result_dstack.shape)
# 输出:
# [[[1 5]
# [2 6]]
# [[3 7]
# [4 8]]]
# 形状: (2, 2, 2)
解释:dstack将arr9和arr10沿深度方向堆叠,创建了一个三维数组,其中每个“层”包含原始数组的元素。
1.4 多维拼接
对于更高维的数组,可以使用np.concatenate指定任意轴进行拼接。例如,axis=2可以用于三维数组的拼接。
# 示例:三维数组拼接
arr11 = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]]) # 形状 (2, 2, 2)
arr12 = np.array([[[9, 10], [11, 12]], [[13, 14], [15, 16]]])
result_concatenate_3d = np.concatenate((arr11, arr12), axis=1)
print("三维数组沿axis=1拼接结果:")
print(result_concatenate_3d)
print("形状:", result_concatenate_3d.shape)
# 输出:
# [[[ 1 2]
# [ 3 4]
# [ 9 10]
# [11 12]]
# [[ 5 6]
# [ 7 8]
# [13 14]
# [15 16]]]
# 形状: (2, 4, 2)
注意:拼接时,所有数组在非拼接轴上的维度必须相同,否则会引发ValueError。
2. 数组分割(Array Splitting)
数组分割是将一个数组分成多个子数组。NumPy提供了split、hsplit和vsplit函数。
2.1 使用split()
split()是通用分割函数,可以沿指定轴分割数组。语法:np.split(array, indices_or_sections, axis=0)。
indices_or_sections:可以是整数(表示分成几个等分)或索引列表(指定分割点)。
# 示例:沿行分割二维数组
arr13 = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]) # 形状 (4, 3)
result_split_axis0 = np.split(arr13, 2, axis=0) # 分成2个等分
print("split沿axis=0分割成2份:")
for i, sub_arr in enumerate(result_split_axis0):
print(f"第{i+1}份:")
print(sub_arr)
# 输出:
# 第1份:
# [[1 2 3]
# [4 5 6]]
# 第2份:
# [[ 7 8 9]
# [10 11 12]]
# 使用索引列表分割
indices = [1, 3] # 在索引1和3处分割(沿axis=0)
result_split_indices = np.split(arr13, indices, axis=0)
print("使用索引分割结果:")
for sub_arr in result_split_indices:
print(sub_arr)
# 输出:
# [[1 2 3]]
# [[4 5 6]
# [7 8 9]]
# [[10 11 12]]
2.2 使用hsplit()
hsplit()专门用于横向分割,沿列方向分割数组。等价于split with axis=1。
# 示例:将数组沿列分割
result_hsplit = np.hsplit(arr13, 3) # 分成3列
print("hsplit分成3列:")
for sub_arr in result_hsplit:
print(sub_arr)
# 输出:
# [[ 1]
# [ 4]
# [ 7]
# [10]]
# [[ 2]
# [ 5]
# [ 8]
# [11]]
# [[ 3]
# [ 6]
# [ 9]
# [12]]
2.3 使用vsplit()
vsplit()专门用于纵向分割,沿行方向分割数组。等价于split with axis=0。
result_vsplit = np.vsplit(arr13, 2) # 分成2行
print("vsplit分成2行:")
for sub_arr in result_vsplit:
print(sub_arr)
# 输出:
# [[1 2 3]
# [4 5 6]]
# [[ 7 8 9]
# [10 11 12]]
注意:分割时,必须确保分割点有效,否则会引发错误。例如,如果数组不能等分,使用整数分割会报错。
3. 注意事项
- 维度一致性:拼接时,所有数组在非拼接轴上的维度必须相同;分割时,分割点必须匹配数组大小。
- 轴参数:理解
axis的含义是关键。对于二维数组,axis=0是行方向,axis=1是列方向;对于更高维数组,轴编号递增对应不同维度。 - 函数选择:
hstack、vstack、dstack是concatenate的便捷版本,适用于特定场景。split、hsplit、vsplit类似。 - 错误处理:在实践中,建议先检查数组形状,避免运行时错误。
4. 总结与练习建议
本教程覆盖了NumPy数组拼接和分割的核心功能。建议读者:
- 动手尝试所有代码示例,修改参数观察变化。
- 创建自己的数组进行练习,例如从随机数生成数组。
- 探索其他NumPy函数,如
stack(用于沿新轴拼接)。 - 在真实数据处理中应用这些操作,如合并多个数据集或分割训练测试数据。
通过本教程,新手应能掌握数组拼接与分割的基础,为进一步学习NumPy打下坚实基础。