在numpy数组中找到切片的位置

6
我有一个ndarray子类,它实现了将一个或多个记录加载/保存到平面二进制文件中。在加载了这些记录之后,我可以按照正常的NumPy方式访问它们。
我的问题是关于当我对结果(或者任何NumPy数组)进行切片时会发生什么。这通常会产生一个“视图”,即一个引用与父数组相同缓冲区的数组。
一旦我有了这个视图,有没有办法确定视图V在数组A中的位置?更准确地说,我想知道从A的数据缓冲区开始算起,V开始的字节偏移量。这将使我能够在正确的偏移量上将切片写回磁盘。
以下是一些示例代码以展示这种情况:
# Imagine a as consisting of 4 4-byte records...
a = np.arange(16, dtype='B').reshape(4,4)

# I select the first record
v = a[0]

print (v)

# [0 1 2 3]

# I can determine that v is a subarray:

is_subarray = v.base != None

# I can determine which dimension the slice spans..

whichdim = v.base.strides.index (v.strides[-1])

# But not its position along that dimension.

为什么不将所需的信息(dim + index)与自定义类一起存储在视图中呢? - Nicolas Barbey
@NicolasBarbey 当然,我可以这样做... 另一方面,NumPy已经知道该切片的位置。 复制该信息似乎很愚蠢(难道没有从NumPy获取该信息的方法吗?) - kampu
难道memmaps对你来说不更有用吗?当然可以得到它......但是不确定会不会顺利。 - seberg
@Sebastian Memmaps很好,但它们目前存在一些问题,让我想远离它们。主要问题是无法保证数组子类的保留,因为a [0] ['x']和a ['x'] [0]不都返回传统数组(其中之一返回'numpy.void',最终结果是与返回标量值不一致的行为)。这一直是令人沮丧的根源。我想子类化某些行为正常的东西(如ndarray) - kampu
1个回答

6
信息可以通过 array.__array_interface__ 暴露出来(也许还有其他更好的方式),但我认为你应该从一开始就使用 memmap,不要折腾这些。例如检查 numpy 代码中的 np.may_share_memory 函数(或者实际上是 np.byte_bounds)。

谢谢!!!特别是给出如此详细的答案...相信我,我希望能够继续使用memmaps。我已经尝试了很长时间(几年)因为我认为它们是在这里使用的东西,就像我说的...当它们工作时,它们很好,但当它们不工作时,它们令人困惑。我会尝试这个方法。 - kampu
3
实际上,np.byte_bounds 是理想的。np.byte_bounds(V) 函数可以得到 V 的字节边界,通过计算 np.byte_bounds(V)[0] - np.byte_bounds(V.base)[0] 可以得出 V 相对于 A 的字节偏移量,根据数组元素的大小和形状,可以轻松地转换成基于记录的偏移量。 - kampu
是的,在1.6.2版本中似乎是这样,谢谢提醒 :) - kampu
@kampu,你在使用memmaps时遇到了什么问题?它们的传播方式很奇怪(x+x会产生一个新的memmap,但实际上并不是),但如果这是你的问题之一,我认为有一个简单的解决方法。 - seberg
准确来说,这实际上是与 memmap recordarrays 相关的问题;在某些情况下 -- arr['fieldname'][index],记得如果我没记错的话,将返回一个 numpy.void 而不是适当的 ndarray 子类,因此某些关键功能将无法使用。 - kampu
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接