0

0

如何高效地从二维张量的每一行中提取不同起始位置的连续子序列

霞舞

霞舞

发布时间:2026-01-06 21:08:01

|

511人浏览过

|

来源于php中文网

原创

如何高效地从二维张量的每一行中提取不同起始位置的连续子序列

本文介绍一种无需显式循环即可从 pytorch 二维张量每行中按指定起始索引和固定长度提取子张量的方法,利用 `torch.arange` 与 `torch.gather` 实现全向量化索引。

深度学习与科学计算中,常需对批量数据(如 N×D 的特征矩阵)按行进行变起点、定长度的切片操作。例如:给定一个形状为 (N, D) 的张量 data,以及长度为 N 的起始索引张量 start_idx,要求对第 i 行提取 data[i, start_idx[i]:start_idx[i] + L],其中 L 为统一子序列长度。若使用 Python 循环或列表推导,不仅低效,还破坏了张量计算的并行性。

PyTorch 提供了高效的向量化方案:构造索引张量 + gather 沿指定维度收集。核心思路是:

  1. 对每个起始索引 start_idx[i],生成对应行的连续索引范围 start_idx[i], start_idx[i]+1, ..., start_idx[i]+L−1;
  2. 将这些范围堆叠成形状为 (N, L) 的二维索引张量;
  3. 调用 data.gather(dim=1, index=index_tensor),沿列维度(dim=1)按行采集指定列索引的值。

注意:start_idx 必须为整数类型(如 torch.long),浮点型索引不被支持;且所有子序列长度必须一致(L 固定),否则无法构成规则索引张量。

以下是完整可运行示例:

WOMBO
WOMBO

使用AI创作美丽的艺术品

下载
import torch

def gather_rows_by_range(data: torch.Tensor, start_idx: torch.Tensor, length: int, dim: int = 1) -> torch.Tensor:
    """
    从 data 的每行(若 dim=1)或每列(若 dim=0)中提取长度为 length 的连续子序列,
    起始位置由 start_idx 指定(按行/列对齐)。

    Args:
        data: 输入张量,形状 (N, D)
        start_idx: 起始索引,形状 (N,),dtype=torch.long
        length: 子序列固定长度(标量)
        dim: 沿哪一维采样(默认 1,即按行取列)

    Returns:
        输出张量,形状 (N, length)
    """
    # 为每行生成 [s, s+1, ..., s+length-1]
    ranges = torch.stack([
        torch.arange(s, s + length, device=data.device, dtype=torch.long)
        for s in start_idx
    ])
    return data.gather(dim, ranges)

# 示例数据
data = torch.tensor([[ 1.,  2.,  3.,  4.,  5.],
                     [ 6.,  7.,  8.,  9., 10.],
                     [11., 12., 13., 14., 15.]])

start_idx = torch.tensor([0, 3, 1], dtype=torch.long)
result = gather_rows_by_range(data, start_idx, length=2, dim=1)

print(result)
# 输出:
# tensor([[ 1.,  2.],
#         [ 9., 10.],
#         [12., 13.]])

优势总结

  • 完全向量化,GPU 友好,避免 Python 循环开销;
  • 支持自动求导(requires_grad=True 时梯度可正确回传);
  • 易扩展至更高维(如 batched 3D 张量,只需调整 dim 和索引构造逻辑)。

⚠️ 注意事项

  • 确保所有 start_idx[i] + length ≤ data.size(dim),否则将触发 IndexError(PyTorch 不做边界检查);
  • 若需动态长度,需改用 torch.nested(v2.0+)或分组 padding + mask,无法直接用 gather;
  • torch.stack 构造索引张量时,若 N 很大,可考虑用广播技巧(如 start_idx.unsqueeze(1) + torch.arange(length))进一步优化内存与速度:
# 更高效的索引张量构造(推荐用于大数据量)
index_tensor = start_idx.unsqueeze(1) + torch.arange(length, device=data.device)
result = data.gather(1, index_tensor)

该方法是 PyTorch 中实现“行级动态切片”的标准实践,在 Transformer 的 sliding window attention、时序模型的 patching 等场景中广泛应用。

相关专题

更多
python开发工具
python开发工具

php中文网为大家提供各种python开发工具,好的开发工具,可帮助开发者攻克编程学习中的基础障碍,理解每一行源代码在程序执行时在计算机中的过程。php中文网还为大家带来python相关课程以及相关文章等内容,供大家免费下载使用。

734

2023.06.15

python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

631

2023.07.20

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

753

2023.07.25

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

617

2023.07.31

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

1258

2023.08.03

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

547

2023.08.04

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

577

2023.08.04

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

705

2023.08.11

PPT动态图表制作教程大全
PPT动态图表制作教程大全

本专题整合了PPT动态图表制作相关教程,阅读专题下面的文章了解更多详细内容。

13

2026.01.07

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 0.6万人学习

Django 教程
Django 教程

共28课时 | 2.9万人学习

SciPy 教程
SciPy 教程

共10课时 | 1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号