You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否将NumPy非反对角线花式索引转换为基础切片索引?

解决方案

可以通过NumPy的 stride 技巧实现,得到的结果是原数组的视图(不复制数据),且内存不连续,同时代码可读性较好。

实现代码

import numpy as np

source = np.arange(400).reshape(20, 20)
# 计算目标序列的步长:每次向下移动1行、向左移动1列,步长为行步长减去列步长
step_stride = source.strides[0] - source.strides[1]
# 从起始点(0,18)开始,按指定步长取10个元素
target = np.lib.stride_tricks.as_strided(source[0, 18], shape=(10,), strides=(step_stride,))

说明

  • 视图特性:as_strided 直接基于原数组的内存缓冲区创建视图,不复制任何数据,和原数组共享内存。
  • 内存不连续:原数组是C连续的(行优先),而目标序列的步长是行步长 - 列步长(例如int64类型下为160-8=152字节),不是单个元素字节数的整数倍,因此内存布局不连续。
  • 结果匹配:该方法获取的元素和原花式索引完全一致,可以通过以下代码验证:
    # 原花式索引的结果
    fancy_indices = np.arange(10), 18 - np.arange(10)
    original_target = source[fancy_indices]
    # 验证两个数组完全相等
    print(np.array_equal(target, original_target))  # 输出 True
    # 验证target是视图(修改原数组会同步改变target)
    source[0,18] = 999
    print(target[0])  # 输出 999
    

可读性优化

如果觉得as_strided的写法不够直观,可以加注释说明逻辑,或者封装成一个简单函数:

def get_offset_diagonal_view(arr, start_row, start_col, length, step_row=1, step_col=-1):
    """获取数组中指定起始点、步长的对角线索引视图"""
    stride = arr.strides[0] * step_row + arr.strides[1] * step_col
    return np.lib.stride_tricks.as_strided(arr[start_row, start_col], shape=(length,), strides=(stride,))

# 调用示例
target = get_offset_diagonal_view(source, start_row=0, start_col=18, length=10)

内容的提问来源于stack exchange,提问作者feiyang472

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 12:53:25