NumPy Concatenate:使用 np.concatenate、vstack 和 hstack 连接数组
Updated on
合并数组是数值计算中最常见的操作之一。你将数据分割进行处理,然后需要重新组合。你从多个来源将特征加载到一个矩阵中。你堆叠多个模型的预测以进行集成。使用 Python 列表通过循环或 + 来合并数组会破坏性能并产生不必要的副本。
NumPy 提供了专门的数组连接函数,这些函数以 C 语言的速度运行,并让你精确控制沿哪个轴进行连接。本指南涵盖了 np.concatenate()、np.vstack()、np.hstack()、np.stack() 及其使用场景。
np.concatenate() -- 核心函数
np.concatenate() 沿现有轴连接一系列数组。
一维数组
import numpy as np
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
c = np.array([7, 8, 9])
result = np.concatenate([a, b, c])
print(result) # [1 2 3 4 5 6 7 8 9]
print(result.shape) # (9,)沿行方向的二维数组(axis=0)
import numpy as np
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])
# 垂直堆叠(添加行)
result = np.concatenate([a, b], axis=0)
print(result)
# [[1 2]
# [3 4]
# [5 6]
# [7 8]]
print(result.shape) # (4, 2)沿列方向的二维数组(axis=1)
import numpy as np
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])
# 水平堆叠(添加列)
result = np.concatenate([a, b], axis=1)
print(result)
# [[1 2 5 6]
# [3 4 7 8]]
print(result.shape) # (2, 4)Shape 要求
所有数组除了连接轴外必须具有相同的形状。
import numpy as np
a = np.ones((3, 4)) # 3 行,4 列
b = np.zeros((2, 4)) # 2 行,4 列
# 正确:不同的行数,相同的列数,axis=0
result = np.concatenate([a, b], axis=0)
print(result.shape) # (5, 4)
# 错误:不同的列数
c = np.ones((3, 5))
# np.concatenate([a, c], axis=0) # ValueError: dimensions don't matchnp.vstack() -- 垂直堆叠
np.vstack() 垂直堆叠数组(沿轴 0)。等同于 np.concatenate(arrays, axis=0),但也能处理一维数组,将其视为单独的行。
import numpy as np
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
# vstack 将一维数组视为行
result = np.vstack([a, b])
print(result)
# [[1 2 3]
# [4 5 6]]
print(result.shape) # (2, 3)
# 对于二维数组
c = np.array([[1, 2], [3, 4]])
d = np.array([[5, 6]])
result = np.vstack([c, d])
print(result)
# [[1 2]
# [3 4]
# [5 6]]np.hstack() -- 水平堆叠
np.hstack() 水平堆叠数组(二维沿轴 1,一维沿轴 0)。
import numpy as np
# 一维数组:像 np.concatenate 一样连接
a = np.array([1, 2, 3])
b = np.array([4, 5])
result = np.hstack([a, b])
print(result) # [1 2 3 4 5]
# 二维数组:添加列
c = np.array([[1], [2], [3]])
d = np.array([[4], [5], [6]])
result = np.hstack([c, d])
print(result)
# [[1 4]
# [2 5]
# [3 6]]np.stack() -- 创建新轴
与 concatenate 不同,stack 沿新轴连接数组,将维度数增加 1。
import numpy as np
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
# 沿新的轴 0 堆叠(默认)
result = np.stack([a, b])
print(result)
# [[1 2 3]
# [4 5 6]]
print(result.shape) # (2, 3)
# 沿新的轴 1 堆叠
result = np.stack([a, b], axis=1)
print(result)
# [[1 4]
# [2 5]
# [3 6]]
print(result.shape) # (3, 2)np.stack() 要求所有输入数组具有相同的形状。
函数比较
| 函数 | 轴 | 创建新轴? | 一维输入处理 |
|---|---|---|---|
np.concatenate | 现有(默认 0) | 否 | 原样连接 |
np.vstack | 0(垂直) | 否 | 将一维视为行 |
np.hstack | 1(水平) | 否 | 连接一维数组 |
np.stack | 新轴 | 是(+1 维度) | 创建新维度 |
np.column_stack | 1 | 否 | 将一维视为列 |
np.row_stack | 0 | 否 | 与 vstack 相同 |
实用示例
为机器学习组合特征
import numpy as np
# 来自不同来源的特征数组
ages = np.array([25, 30, 35, 40])
incomes = np.array([50000, 60000, 75000, 90000])
scores = np.array([720, 680, 750, 800])
# 按列堆叠以创建特征矩阵
X = np.column_stack([ages, incomes, scores])
print(X)
# [[ 25 50000 720]
# [ 30 60000 680]
# [ 35 75000 750]
# [ 40 90000 800]]
print(X.shape) # (4, 3)批处理结果
import numpy as np
# 分批处理数据,合并结果
results = []
for batch_start in range(0, 100, 25):
batch = np.random.randn(25, 10) # 25 个样本,10 个特征
processed = batch * 2 + 1 # 一些处理
results.append(processed)
# 垂直合并所有批次
all_results = np.vstack(results)
print(all_results.shape) # (100, 10)图像处理 -- 合并通道
import numpy as np
height, width = 100, 100
# 分离的颜色通道
red = np.random.randint(0, 256, (height, width))
green = np.random.randint(0, 256, (height, width))
blue = np.random.randint(0, 256, (height, width))
# 合并为 RGB 图像
rgb_image = np.stack([red, green, blue], axis=2)
print(rgb_image.shape) # (100, 100, 3)可视化合并数据
连接来自不同来源的数组后,PyGWalker (opens in a new tab) 让你在 Jupyter 中交互式地探索合并后的数据集:
import pandas as pd
import pygwalker as pyg
# 将连接后的数组转换为 DataFrame
df = pd.DataFrame(X, columns=['age', 'income', 'score'])
walker = pyg.walk(df)常见问题
np.concatenate 和 np.stack 有什么区别?
np.concatenate 沿现有轴连接数组而不改变维度数。np.stack 沿新轴连接数组,增加一个维度。例如,用 concatenate 堆叠两个 (3,) 数组得到 (6,),而 stack 得到 (2, 3)。
np.concatenate 中的 axis 是什么意思?
axis 参数指定沿哪个维度连接。axis=0 沿行连接(添加更多行),axis=1 沿列连接(添加更多列)。对于二维数组,axis=0 是垂直堆叠,axis=1 是水平堆叠。
什么时候应该使用 vstack、hstack 还是 concatenate?
使用 vstack 添加行(垂直堆叠),hstack 添加列(水平堆叠),当需要指定任意轴时使用 concatenate。vstack 和 hstack 是便捷函数,比 concatenate 更直观地处理一维数组。
为什么连接数组时会出现 ValueError?
所有数组除了连接轴外必须具有相同的形状。如果沿 axis=0 连接,所有数组必须具有相同的列数。连接前使用 array.shape 检查形状。
如何连接不同维度的数组?
首先将数组重塑为兼容的维度。使用 np.expand_dims(array, axis) 添加一个维度,或使用 array.reshape(new_shape)。例如,要将一维数组与二维数组进行 vstack,重塑一维数组:array.reshape(1, -1)。
总结
NumPy 提供了完整的数组连接工具包:np.concatenate() 用于沿任意轴的通用连接,np.vstack()/np.hstack() 用于直观的垂直/水平堆叠,np.stack() 用于需要创建新维度的场景。记住 concatenate 沿现有轴连接而 stack 创建新轴。仔细匹配维度,在常见的行/列操作中使用 vstack/hstack 以获得最易读的代码。