numpy:如果 numpy 数组是视图,则可靠(非保守)指示符
Posted
技术标签:
【中文标题】numpy:如果 numpy 数组是视图,则可靠(非保守)指示符【英文标题】:numpy: Reliable (non-conservative) indicator if numpy array is view 【发布时间】:2016-02-05 11:20:48 【问题描述】:寻找一种方法来可靠地识别 numpy 对象是否是视图。
相关问题之前出现过很多次(here、here、here),也有人提出了一些解决方案,但似乎都有问题:
现在pandas
中使用的测试是在my_array.base is not None
中调用某个视图。这似乎总能捕获视图,但也提供了许多误报(它报告某些内容的情况是视图,即使它不是视图)。
numpy.may_share_memory()
将检查两个特定数组,但一般不会回答
(@RobertKurn 说它是 2012 年最好的工具——有什么变化吗?)
flags['OWNDATA'])
是 reported (third comment first answer) 在某些情况下会失败。
(我感兴趣的原因是我正在为 pandas 实现写时复制,保守的指标导致过度复制。)
【问题讨论】:
关于numpy github tracker的相关讨论:github.com/numpy/numpy/issues/5604 被描述为误报的情况似乎是“创建副本”的操作实际上返回副本的视图。如果这被认为是“不是视图”,您可以尝试检查数组的base
的引用计数,以查看是否有其他对它的引用,但这并不完美。我认为不可能可靠地检测到这种事情。
另见这个最近的 SO 问题,***.com/questions/33467477/…。它提到了一个新功能,np.shares_memory
。但我强调,比较 2 个已知变量是一回事,另一个要问的是数组与任何其他数组共享数据缓冲区。
一个 numpy 数组和稍后创建的视图怎么样,你想如何处理原始数组?
就我而言,原件可以视为“不是视图”。
【参考方案1】:
根据您的使用情况,flags['OWNDATA']
可以完成这项工作。
实际上,您的链接没有问题。 在某些情况下它不会失败。它总是会做它应该做的事情。
根据http://docs.scipy.org/doc/numpy-1.10.0/reference/generated/numpy.require.html:标志“确保数组拥有自己的数据”。
在您的“反例”中,他们使用代码:
print (b.flags['OWNDATA']) #False -- apparently this is a view
e = np.ravel(b[:, 2])
print (e.flags['OWNDATA']) #True -- Apparently this is a new numpy object.
但是,在第二种情况下为 True 是正常行为。
它来自ravel
的定义(来自http://docs.scipy.org/doc/numpy-1.10.1/reference/generated/numpy.ravel.html)。
返回一个连续的扁平数组。 返回一个包含输入元素的一维数组。仅在需要时才制作副本。
这里需要一个副本,所以制作了一个副本。因此,变量 e 真正拥有自己的数据。它不是“b 的视图”、“b 的引用”、“b 的一部分的别名”。这是一个真正的新数组,包含 b 的一些元素的副本。
所以,我认为如果不跟踪数据的整个来源来检测这种行为是不可能的。我相信您应该能够使用该标志构建您的程序。
【讨论】:
以上是关于numpy:如果 numpy 数组是视图,则可靠(非保守)指示符的主要内容,如果未能解决你的问题,请参考以下文章
python使用numpy的array_equal函数判断两个numpy数组是否具有相同的形状(shape)和元素(elements)如果都满足则返回True否则返回False