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

NumPy中如何判断数组不同视图的索引是否指向同一内存?

问题背景

现有形状为(h,w)的数组in,给定常量s,可通过以下代码生成滑动窗口视图strided_in:

new_h = (h - k_h)//s + 1
new_w = (w - k_w)//s + 1
s_h, s_w = in.strides
new_shape = (new_h, new_w,k_h,k_w)
new_strides = (s_h * s, s_w * s, s_h, s_w)
strided_in = np.lib.stride_tricks.as_strided(in,new_shape, new_strides)

该视图是将(k_h,k_w)形状的子数组以步长s在原数组上滑动得到的窗口矩阵。通过out = np.max(strided_arr, axis=(2,3))得到输出数组out后,已知与out形状一致的grad_out,需要计算和原数组in形状一致的grad_in,其元素计算逻辑如下:

grad_in[i,j] = 0
for m, row in enumerate(strided_in):
    for n, block in enumerate(row):
        grad_in[i,j] += grad_out[m,n] * (np.max(block) == in[i,j])

即当in[i,j]是某个窗口的最大值时,累加对应的grad_out[m,n]。但原数组中元素可能重复,会导致重复计数——比如基础数组arr1 = [1, 1]和其视图arr2 = [[1],[1]],需要明确区分arr1[0]和arr2[1,0]对应的内存位置。已知np.shares_memory可判断数组是否共享内存,但无法针对单个元素做判断。

核心问题

NumPy中是否有函数能判断不同数组视图的两个索引是否指向同一内存?

解决方案

NumPy没有直接提供针对单个元素的内存地址判断函数,但可以通过计算元素的内存偏移量来实现:

  • 对于任意数组(或视图)arr及其合法索引idx(多维索引用元组表示),先计算该元素相对于数组起始地址的偏移量:
    offset = arr.strides @ np.array(idx)
    
  • 获取数组的起始内存地址:
    base_addr = arr.__array_interface__['data'][0]
    
  • 两个元素指向同一内存的充要条件是:它们的起始地址 + 偏移量完全相等。

以问题中的arr1和arr2为例:

import numpy as np

arr1 = np.array([1, 1])
arr2 = np.lib.stride_tricks.as_strided(arr1, shape=(2,1), strides=(arr1.strides[0], 0))

# 计算arr1[0]的内存地址
addr_arr1_0 = arr1.__array_interface__['data'][0] + arr1.strides @ (0,)
# 计算arr2[1,0]的内存地址
addr_arr2_10 = arr2.__array_interface__['data'][0] + arr2.strides @ (1, 0)

# 判断是否指向同一内存
print(addr_arr1_0 == addr_arr2_10)  # 输出False,因为arr2[1,0]实际指向arr1[1]

注意事项

  • 该方法仅适用于共享同一基础内存的数组视图,若数组是拷贝生成的,起始地址会不同,直接比较即可排除。
  • 必须确保索引是合法的,避免越界访问导致错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 21:32:45