尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

【Numpy】第四部分:数据拼接、拆分与变形(工程篇)

【Numpy】第四部分:数据拼接、拆分与变形(工程篇) 第四部分数据拼接、拆分与变形工程篇在处理多源异构数据或构建复杂的系统仿真时经常需要将不同维度的计算结果拼接成增广矩阵例如状态空间中的[A∣B][A\vert{}B][A∣B]矩阵或者提取长序列中的时间窗口。本篇重点介绍如何像拼积木一样高效地重组和切割数据块。1. 矩阵拼接将多个已有的数组按指定维度组合成一个更大的数组。在控制仿真中常用于合并系统状态向量与控制输入序列。np.concatenate: 最通用的拼接函数允许指定任意已存在的轴axis进行拼接。要求除了拼接轴之外参与拼接的所有数组在其他维度上的形状必须完全一致。importnumpyasnp# 两个批次的状态数据每个批次包含 2 个样本每个样本有 3 个状态量 (2, 3)batch1np.array([[1.0,0.5,0.1],[1.2,0.4,0.2]])batch2np.array([[0.9,0.6,0.0],[1.1,0.5,0.1]])# 按第 0 轴行方向拼接合并样本形状变为 (4, 3)combined_batchesnp.concatenate((batch1,batch2),axis0)print(combined_batches.shape)# (4, 3)np.vstack: 垂直拼接按行堆叠。等价于np.concatenate(..., axis0)但语义更明确适合处理时间序列的逐帧追加。x1np.array([1,2,3])x2np.array([4,5,6])# 将一维向量按行堆叠成二维矩阵V_stackednp.vstack((x1,x2))print(V_stacked)# [[1 2 3]# [4 5 6]]np.hstack: 水平拼接按列堆叠。常用于构造增广矩阵。Anp.array([[1,2],[3,4]])# 系统矩阵 A (2, 2)Bnp.array([[0],[1]])# 输入矩阵 B (2, 1)# 构造增广矩阵 [A | B]Augmented_Mnp.hstack((A,B))print(Augmented_M)# [[1 2 0]# [3 4 1]]np.dstack: 深度拼接按第 3 个维度叠加。在处理多通道图像、空地协同环境的三维栅格地图或将二维平面状态堆叠至时间轴时非常有用。# 两个 2x2 的平面坐标网络grid_xnp.array([[0,1],[0,1]])grid_ynp.array([[0,0],[1,1]])# 将 X 和 Y 坐标堆叠成形状为 (2, 2, 2) 的张量coordsnp.dstack((grid_x,grid_y))print(coords[0,1])# 输出第一行第二列元素的坐标 (X, Y)# [1 0]2. 分块拼接在设计 LQR/MPC 控制器或处理复杂系统参数时往往需要用多个小矩阵组合成一个大矩阵。np.block: 允许按照直观的嵌套列表形式创建分块矩阵极大简化了复杂增广矩阵的构造代码。Anp.eye(2)# 2x2 单位阵Bnp.array([[0],[1]])# 2x1 向量Cnp.array([[1,0]])# 1x2 向量Dnp.array([[0]])# 1x1 标量# 按照系统分块矩阵 [ A, B ]# [ C, D ] 的形式组合System_Matrixnp.block([[A,B],[C,D]])print(System_Matrix)# [[1. 0. 0.]# [0. 1. 1.]# [1. 0. 0.]]3. 数组拆分与拼接相对拆分函数用于将大数组切割为多个小数组。np.split: 通用的拆分函数可将数组沿指定轴等分或在指定的索引位置切断。datanp.array([10,20,30,40,50,60])# 指定索引位置拆分在索引 2 和 5 处切断分为 3 段chunksnp.split(data,[2,5])print(chunks)# [array([10, 20]), array([30, 40, 50]), array([60])]np.vsplit与np.hsplit: 分别对应垂直拆分切断行与水平拆分切断列。matrixnp.array([[1,2,3,4],[5,6,7,8]])# 将 4 列平均水平拆分为两个 (2, 2) 的矩阵left,rightnp.hsplit(matrix,2)print(Left part:\n,left)# [[1 2]# [5 6]]4. 排列与滚动在无模型自适应控制 (MFAC) 算法中常需要维护历史 I/O 数据的滑动窗口在多智能体编队中往往需要将期望轨迹复制给系统中的所有智能体。np.roll: 使数组元素沿着指定轴进行循环位移。这是在 Python 中实现 FIFO先进先出数据缓冲区或时间序列滑动窗口的最高效方法之一无需频繁分配内存。# 模拟一个长度为 5 的历史输入数据缓冲区 (u_{k-4} 到 u_k)buffernp.array([1.1,1.2,1.3,1.4,1.5])# 新时刻到来输入了新控制量 1.6new_u1.6# 将旧数据整体向左滚动 1 位挤掉最老的数据并在末尾追加新数据buffernp.roll(buffer,shift-1)buffer[-1]new_uprint(更新后的缓冲区:,buffer)# 更新后的缓冲区: [1.2 1.3 1.4 1.5 1.6]np.tile: 将整个数组作为一个基本单元按照指定的次数进行瓦片式重复平铺。ref_trajnp.array([10.0,20.0])# 某个二维参考点# 为编队内的 3 个智能体分配同样的参考点 (形状变为 3x2)multi_agent_refsnp.tile(ref_traj,(3,1))print(multi_agent_refs)# [[10. 20.]# [10. 20.]# [10. 20.]]np.repeat: 将数组中的各个元素分别重复指定次数而不是重复整个数组块。commandsnp.array([0,1])# [直行, 转向]# 每个指令维持 3 个控制周期step_commandsnp.repeat(commands,3)print(step_commands)# [0 0 0 1 1 1]
返回列表