给定 numpy 数组视图中项目的索引,在基本数组中找到它的索引

given the index of an item in a view of a numpy array, find its index in the base array

假设 a 是一个形状为 (N,)b = a[k:l] 的 numpy 数组。我知道 x = b[i],有没有办法在不知道 kl 并且不在 a 中搜索 x = a[j] 的情况下找到 j =19=]?

例如a = np.array([2,4,3,1,7])b = a[1:4]。我只能访问 b,但想知道 3a 中的索引是什么,知道它在 b 中的索引是 1

当然我可以使用 b.base 访问 a,然后在 a 中搜索项目 3,但我想知道是否有附加的方法查看其中 returns 基本数组中项目的索引。

正如@hpaulj 已经在评论中指出的那样,没有内置功能可以这样做。但是您仍然可以根据 dtype 的大小和基与视图之间的字节偏移来计算基的索引。您可以从属性 ndarray.__array_interface__['data'][0]

中获取字节偏移量
import numpy as np
import unittest

def baseIndex(array: np.ndarray, index: int) -> int:
    base = array.base
    if base is None:
        return index
    size = array.dtype.itemsize
    stride = array.strides[0] // size
    offset = (array.__array_interface__['data'][0] - base.__array_interface__['data'][0]) // size
    return offset + index * stride

a = np.array([0,1,2,3,4,5,6])
b = a
class Test(unittest.TestCase):

    def test_1_simple(self):
        """b = a"""
        b = a
        i = 1
        j = baseIndex(b, i)
        self.assertEqual(a[j], b[i])
    
    def test_2_offset(self):
        """b = a[3:]"""
        b = a[3:]
        i = 1
        j = baseIndex(b, i)
        self.assertEqual(a[j], b[i])
    
    def test_3_strided(self):
        """b = a[1::2]"""
        b = a[1::2]
        i = 1
        j = baseIndex(b, i)
        self.assertEqual(a[j], b[i])
    
    def test_4_reverse_strided(self):
        """b = a[4::-2]"""
        b = a[4::-2]
        i = 1
        j = baseIndex(b, i)
        self.assertEqual(a[j], b[i])


unittest.main(verbosity=2)

输出:

test_1_simple (__main__.Test)
b = a ... ok
test_2_offset (__main__.Test)
b = a[3:] ... ok
test_3_strided (__main__.Test)
b = a[1::2] ... ok
test_4_reverse_strided (__main__.Test)
b = a[4::-2] ... ok

----------------------------------------------------------------------
Ran 4 tests in 0.001s

OK

编辑:我现在更新了函数来处理 b 不连续 and/or 反向的情况,感谢@Jérôme Richard 发现了这一点。此外,正如@mozway 所述,ndarray.__array_interface__ 是一个内部 numpy 细节,可以在不另行通知的情况下更改,但截至目前我还没有看到任何其他方法可以这样做。