本系列是《NumPy 速通》的配套章节。

把多个数组合并(拼接),或者把一个数组拆开(分割)——数据处理和特征工程里很常用。本章核心:concatenate(通用)、vstack/hstack(直观)、split(分割),以及一个灵魂警告:拼接出的新数组和原数组的关系。

拼接:concatenate(最通用的一个)

import numpy as np

a = np.array([1, 2, 3])
b = np.array([4, 5, 6])

np.concatenate([a, b])   # [1 2 3 4 5 6]  一维:直接接一起
np.concatenate([a, b, a])# [1 2 3 4 5 6 1 2 3]  可以传多个

二维数组可以指定沿行还是沿列拼:

x = np.array([[1, 2], [3, 4]])
y = np.array([[5, 6], [7, 8]])

np.concatenate([x, y], axis=0)  # 沿行方向拼 → 上下堆叠 (4,2)
# [[1 2]
#  [3 4]
#  [5 6]
#  [7 8]]

np.concatenate([x, y], axis=1)  # 沿列方向拼 → 左右拼接 (2,4)
# [[1 2 5 6]
#  [3 4 7 8]]

⚠️ 灵魂警告:拼接的数组必须"形状兼容"。

  • axis=0 拼接:除第 0 维外,其余维度必须相等(列数要一样)
  • axis=1 拼接:行数要一样
  • 违反则报 ValueError: all the input array dimensions ... must match

常见场景:两个数据集的列数不一样(一个多了个特征列)→ 想按行拼会报错,先对齐列。

堆叠:vstack / hstack(直观写法)

比 concatenate 更好记的专用函数:

np.vstack([a, b])   # vertical 垂直堆叠(变两行)
# [[1 2 3]
#  [4 5 6]]

np.hstack([a, b])   # horizontal 水平拼接
# [1 2 3 4 5 6]

np.stack([a, b])    # 沿新维度堆叠 → (2,3),多出一个维度
# [[1 2 3]
#  [4 5 6]]

np.dstack([a, b])   # 沿深度方向堆叠 → (1,3,2),三维
函数 方向 结果 shape(a、b 都是 (3,))
vstack 垂直(行) (2, 3)
hstack 水平(列) (6,)
stack 新轴 (2, 3)
dstack 深度 (1, 3, 2)

💡 vstack 会把一维数组"自动变成行向量"再叠((3,) → (1,3));hstack 对一维是直接接长。这点和 concatenate(要求精确 shape)不同,更省心。stack 常用于批量处理多个样本(如 5 个特征向量 → 一个 (5, n) 矩阵)。

vstack / hstack 与 concatenate 的对应

np.vstack([x, y])     ==  np.concatenate([x, y], axis=0)
np.hstack([x, y])     ==  np.concatenate([x, y], axis=1)

分割:split

arr = np.arange(10)

np.split(arr, 2)      # 平均分成 2 份
# [array([0,1,2,3,4]), array([5,6,7,8,9])]

np.split(arr, [3, 7]) # 在索引 3 和 7 处切开 → 3 份
# [array([0,1,2]), array([3,4,5,6]), array([7,8,9])]

np.array_split(arr, 3)  # 尽量均分(不能整除也不报错)
# [array([0,1,2,3]), array([4,5,6]), array([7,8,9])]

关键区别:

  • np.split(arr, n):必须能整除,否则报错
  • np.array_split(arr, n):尽量均分,不能整除也不报错(更宽容)
  • np.split(arr, [3, 7]):按索引列表切(位置切分)

二维分割:

data = np.arange(24).reshape(4, 6)
np.split(data, 2, axis=0)   # 上下切成 2 块(每块 2 行)
np.split(data, 3, axis=1)   # 左右切成 3 块(每块 2 列)

常用场景

场景一:合并多个数据文件

parts = [np.load(f"data_{i}.npy") for i in range(5)]
full = np.concatenate(parts)   # 合并成一个大数据集再统一处理

场景二:训练集/验证集切分

X = np.arange(1000).reshape(100, 10)

# 前 80% 训练、后 20% 验证
X_train, X_val = np.split(X, [80], axis=0)
print(X_train.shape, X_val.shape)   # (80,10) (20,10)

场景三:批量数据升维

# 5 张 3×3 的图像"样本"
imgs = np.stack([img1, img2, img3, img4, img5])  # (5, 3, 3)

小结

  1. concatenate:通用拼接,axis=0/1 控制方向
  2. vstack/hstack/stack:直观堆叠,一维自动变行
  3. split / array_split:按份数或按位置切分;array_split 不要求整除
  4. ⚠️ 拼接前检查形状兼容(列数/行数一致)
  5. 组合拳:split 切训练/验证集 → concatenate 合并数据集 → stack 做批量样本

下一章:把数组存到磁盘、再读回来。


上一篇:第 9 章 布尔索引与筛选 | 下一篇:第 11 章 文件读写


上一篇:第 9 章 布尔索引与筛选 | 下一篇:第 11 章 文件读写