以下是对 NumPy 中用于合并(或组合)多个数组的函数 的全面、系统、深入且结构清晰的详解。我们将涵盖所有主流函数(包括 concatenate、stack、vstack、hstack、dstack、column_stack、row_stack、block、r_/c_ 等),详细说明其:
- 功能原理
- 输入要求
- 输出形状
- 与其它函数的关系
- 典型应用场景
- 常见陷阱与注意事项
并辅以大量代码示例和对比表格,确保你彻底掌握 NumPy 数组合并的全貌。
一、核心概念:什么是“合并”?
在 NumPy 中,“合并”通常指将两个或多个数组组合成一个更大的数组。根据是否引入新维度,可分为两类:
- 沿已有轴拼接(Concatenation):不增加维度,只是延长某个方向。
- 如:把两个 (3,) 向量拼成 (6,) 向量。
- 沿新轴堆叠(Stacking):创建一个新维度,将原数组作为“切片”放入。
- 如:把两个 (3,) 向量堆成 (2, 3) 矩阵。
理解这一区别是掌握所有合并函数的关键。
二、主要合并函数详解
1. np.concatenate
功能
沿已存在的轴连接数组序列。
语法
np.concatenate(arrays, axis=0, out=None)
要求
- 所有输入数组必须具有相同的维数(ndim)。
- 除
axis维度外,其余维度的大小必须完全一致。
输出形状
与输入数组相同维度,仅 axis 方向长度相加。
示例
# 1D
a = np.array([1, 2]); b = np.array([3, 4])
np.concatenate([a, b]) # [1 2 3 4], shape=(4,)
# 2D, axis=0(行拼接)
A = np.array([[1, 2]]); B = np.array([[3, 4]])
np.concatenate([A, B], axis=0) # [[1 2], [3 4]], shape=(2,2)
# 2D, axis=1(列拼接)
C = np.array([[1], [2]]); D = np.array([[3], [4]])
np.concatenate([C, D], axis=1) # [[1 3], [2 4]], shape=(2,2)
注意
- 不支持自动升维。若想拼接 1D 到 2D,需先 reshape。
axis=None会先展平所有数组再拼接(等价于np.hstack+ flatten)。
2. np.stack
功能
沿新创建的轴堆叠数组,强制所有输入形状完全相同。
语法
np.stack(arrays, axis=0, out=None)
要求
- 所有数组必须形状完全一致(包括维度数和各维大小)。
axis可为负值(如axis=-1表示最后一维)。
输出形状
原形状插入一个新维度:new_shape = old_shape[:axis] + (N,) + old_shape[axis:],其中 N 是数组个数。
示例
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
# 默认 axis=0
np.stack([a, b])
# [[1 2 3]
# [4 5 6]], shape=(2,3)
# axis=1
np.stack([a, b], axis=1)
# [[1 4]
# [2 5]
# [3 6]], shape=(3,2)
# 2D 示例
X = np.ones((2,3)); Y = np.zeros((2,3))
np.stack([X, Y], axis=2) # shape=(2,3,2)
与 concatenate 对比
| 特性 | concatenate | stack |
|---|---|---|
| 是否新增维度 | ❌ | ✅ |
| 输入形状要求 | 除 axis 外一致 | 完全一致 |
| 用途 | 扩展数据集 | 构造高维结构(batch、通道等) |
3. np.vstack(Vertical Stack)
功能
垂直堆叠(按行方向拼接)。对 1D 数组特殊处理:自动升维为 (1, n)。
等价形式
- 对 ≥2D 数组:
np.concatenate(..., axis=0) - 对 1D 数组:先 reshape 为
(1, n)再拼接
示例
# 1D → 自动升维
a = np.array([1, 2]); b = np.array([3, 4])
np.vstack([a, b])
# [[1 2]
# [3 4]], shape=(2,2)
# 2D
A = np.array([[1, 2]]); B = np.array([[3, 4]])
np.vstack([A, B]) # same as concatenate(axis=0)
注意
- 不适用于标量(0D)。
- 若混合 1D 和 2D,需确保列数匹配。
4. np.hstack(Horizontal Stack)
功能
水平堆叠(按列方向拼接)。
行为
- 对 1D:直接拼接成更长的 1D(等价于
concatenate) - 对 ≥2D:
concatenate(..., axis=1)
示例
# 1D
a = [1,2]; b = [3,4]
np.hstack([a,b]) # [1 2 3 4]
# 2D
A = [[1],[2]]; B = [[3],[4]]
np.hstack([A,B]) # [[1,3],[2,4]]
5. np.dstack(Depth Stack)
功能
沿**第 3 轴(深度)**堆叠,常用于图像通道合并。
等价
- 对 2D 数组:
np.stack(..., axis=2) - 对 1D 数组:先升维为
(1,1,n)?实际行为更复杂,建议避免混用。
示例
a = np.array([[1, 2]])
b = np.array([[3, 4]])
np.dstack([a, b])
# [[[1 3]
# [2 4]]], shape=(1,2,2)
常用于将 R、G、B 三个 (H,W) 图像合成 (H,W,3) 彩色图。
6. np.column_stack
功能
将 1D 或 2D 数组按列组合成 2D 矩阵。
特殊规则
- 对 1D 数组:视为列向量(自动转为
(n,1)) - 对 2D 数组:直接按列拼接(同
hstack)
示例
x = np.array([1, 2, 3]) # (3,)
y = np.array([4, 5, 6]) # (3,)
np.column_stack([x, y])
# [[1 4]
# [2 5]
# [3 6]] ← 每个输入成为一列
# 与 stack(axis=1) 等价
np.stack([x, y], axis=1) # 相同结果
非常适合将多个特征向量组合成设计矩阵(design matrix)。
7. np.row_stack
功能
等价于 np.vstack,仅为语义清晰提供别名。
np.row_stack == np.vstack # True
8. np.block
功能
最灵活的合并函数,支持嵌套列表构建分块矩阵(block matrix)。
特点
- 可混合不同形状的子数组(只要最终能对齐)
- 支持任意嵌套层级
- 自动推断维度
示例
A = np.eye(2) * 2 # [[2,0],[0,2]]
B = np.ones((2,3)) # [[1,1,1],[1,1,1]]
C = np.zeros((3,2)) # [[0,0],[0,0],[0,0]]
D = np.eye(3) * 3 # 3x3
# 构建分块矩阵 [[A, B],
# [C, D]]
M = np.block([[A, B],
[C, D]])
print(M.shape) # (5, 5)
类似 MATLAB 的
[A B; C D]语法。
注意
- 子块必须在非拼接维度上对齐(如 A 和 B 必须行数相同)。
- 比
concatenate更高层,适合构造复杂结构。
9. np.r_ 和 np.c_(便捷索引器)
功能
通过类似切片的语法快速拼接数组。
np.r_:类似vstack(按行)np.c_:类似column_stack(按列)
示例
# r_: 拼接行(1D 变多行)
np.r_[1:4, 0, 0] # [1 2 3 0 0]
a = np.array([1,2]); b = np.array([3,4])
np.r_[a, b] # [1 2 3 4] (1D 拼接)
# c_: 拼接列
np.c_[a, b]
# [[1 3]
# [2 4]]
# 也可用于生成网格
x = np.array([1,2]); y = np.array([10,20])
np.c_[x, y, x+y]
# [[1 10 11]
# [2 20 22]]
底层调用
concatenate或column_stack,适合交互式使用。
三、函数关系与等价性总结
| 函数 | 等价表达式 | 适用场景 |
|---|---|---|
vstack | concatenate(axis=0)(对 ≥2D)1D 自动升维 | 快速上下拼接 |
hstack | concatenate(axis=1)(对 ≥2D)1D 直接拼接 | 快速左右拼接 |
dstack | stack(axis=2)(对 2D) | 图像通道、深度堆叠 |
column_stack | stack(axis=1)(对 1D)hstack(对 2D) | 特征列组合 |
row_stack | vstack | 语义清晰 |
r_ / c_ | 封装了 concatenate/column_stack | 快捷交互式拼接 |
block | 多层 concatenate 组合 | 复杂分块矩阵 |
四、选择指南:何时用哪个?
| 场景 | 推荐函数 |
|---|---|
| 合并两个样本列表(如训练集+验证集) | concatenate |
| 将多个向量组成矩阵的列 | column_stack 或 stack(axis=1) |
| 构造 batch 数据(如 10 张图像 → (10, H, W)) | stack |
| RGB 三通道合成彩色图像 | dstack 或 stack(axis=-1) |
| 快速上下拼接表格数据 | vstack |
| 快速左右拼接特征 | hstack |
| 构建分块矩阵(如线性代数中的增广矩阵) | block |
| 交互式快速拼接 | r_ / c_ |
五、常见错误与调试技巧
-
维度不匹配
- 报错:
ValueError: all the input array dimensions except for the concatenation axis must match exactly - 解决:检查
shape,必要时用reshape或np.newaxis调整。
- 报错:
-
axis 越界
- 1D 数组没有
axis=1 - 解决:先确认数组维度:
arr.ndim
- 1D 数组没有
-
混淆 stack 与 concatenate
- 错误预期:以为
stack会延长数组 - 正确理解:
stack是“打包”,concatenate是“拉长”
- 错误预期:以为
-
混合 1D/2D 导致意外升维
vstack([1D, 2D])可能出错- 建议:统一输入维度后再操作
六、性能提示
concatenate通常比stack更高效(不新增维度)- 频繁拼接大数组时,应预先分配内存(避免多次拷贝)
- 对于大量小数组拼接,考虑用
list.append+ 一次concatenate
七、总结
NumPy 提供了丰富而灵活的数组合并工具,核心在于理解:
- 是否新增维度(
stackvsconcatenate) - 拼接方向(axis=0 行,axis=1 列,axis=2 深度)
- 输入形状约束
掌握这些函数后,你可以高效地处理从简单数据拼接到复杂张量构建的各种任务。
1637

被折叠的 条评论
为什么被折叠?



