给定 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]
,有没有办法在不知道 k
和 l
并且不在 a
中搜索 x = a[j]
的情况下找到 j
=19=]?
例如a = np.array([2,4,3,1,7])
和b = a[1:4]
。我只能访问 b
,但想知道 3
在 a
中的索引是什么,知道它在 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 细节,可以在不另行通知的情况下更改,但截至目前我还没有看到任何其他方法可以这样做。
假设 a
是一个形状为 (N,)
和 b = a[k:l]
的 numpy 数组。我知道 x = b[i]
,有没有办法在不知道 k
和 l
并且不在 a
中搜索 x = a[j]
的情况下找到 j
=19=]?
例如a = np.array([2,4,3,1,7])
和b = a[1:4]
。我只能访问 b
,但想知道 3
在 a
中的索引是什么,知道它在 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 细节,可以在不另行通知的情况下更改,但截至目前我还没有看到任何其他方法可以这样做。