假设我有一个numpy
数组a
,并创建{
a = np.arange(3)
b = a
如果我现在改变b
,例如这样
并打印a
,b
,它们的id
和{
print a
print a.flags
print b
print b.flags
print id(a)
print id(b)
我得到
[100 1 2]
C_CONTIGUOUS : True
F_CONTIGUOUS : True
OWNDATA : True
WRITEABLE : True
ALIGNED : True
UPDATEIFCOPY : False
[100 1 2]
C_CONTIGUOUS : True
F_CONTIGUOUS : True
OWNDATA : True
WRITEABLE : True
ALIGNED : True
UPDATEIFCOPY : False
139767698376944
139767698376944
因此,a
和{id
和预期的一样。在
当我现在使用copy()
执行相同操作时
c = np.arange(3)
d = c.copy()
d[0] = 20
print c
print c.flags
print id(c)
print d
print d.flags
print id(d)
我明白了
[0 1 2]
C_CONTIGUOUS : True
F_CONTIGUOUS : True
OWNDATA : True
WRITEABLE : True
ALIGNED : True
UPDATEIFCOPY : False
139767698377344
[20 1 2]
C_CONTIGUOUS : True
F_CONTIGUOUS : True
OWNDATA : True
WRITEABLE : True
ALIGNED : True
UPDATEIFCOPY : False
139767698376864
在本例中,c
和{id
也与预期一样。在
然而,让我困惑的是我从.flags
获得的输出:在所有情况下,OWNDATA
都被设置为True
。当我阅读documentation时,我发现:
OWNDATA (O) The array owns the memory it uses or borrows it from another object.
我现在的主要问题是:
找到指向同一个id
(在上面的例子中是a
和{OWNDATA
会有帮助,但显然不是这样。在
相关问题:
OWNDATA
实际用于什么,在这种情况下,OWNDATA
被设置为False
?在
赋值}。在
b=a
不在原始数组a
上创建视图,而只是创建对它的引用。换句话说,b
只是a
的不同名称。变量a
和b
都引用拥有其数据的同一数组,因此设置了OWNDATA
标志。修改b
将修改{赋值}分别引用各自的数据数组,从而设置了
b=a.copy()
创建原始数组的副本。也就是说,a
和{OWNDATA
标志。修改b
不会修改a
。在但是,如果进行赋值}。在
b=a[:]
,则将创建原始数组的视图,b
将不拥有其数据。修改b
将修改{^{} 函数就是您要查找的。它按照方框上的说明执行:检查to数组
a
和b
是否具有共享内存,从而相互影响。在有两个问题-如何识别要比较的变量,以及如何比较它们。在
先拿第二个。在
我的版本(1.8.2)没有
np.shares_memory
函数。它有一个np.may_share_memory
。在https://github.com/numpy/numpy/pull/6166是添加
shares_memory
的拉请求;它的日期是去年8月。所以你必须有全新的numpy
才能使用它。请注意,最终测试可能很难,并且可能会发出“TOO hard”错误消息。例如,我想象有一些片共享内存,但是很难通过简单地比较缓冲区起始点来确定。在https://github.com/numpy/numpy/blob/97c35365beda55c6dead8c50df785eb857f843f0/numpy/core/tests/test_mem_overlap.py是这些
memory_overlap
函数的单元测试。如果你想知道两个已知阵列之间所有可能的重叠情况是一项多么艰巨的任务,请阅读它。在我喜欢看数组的
.__array_interface__
。字典中的一个条目是“data”,它是指向数据缓冲区的指针。指针相同意味着数据是共享的。但一个观点可能会从某个地方开始。如果shares_memeory
看到这个指针,我不会感到惊讶。在相同的
id
表示两个变量引用同一个对象,但不同的数组对象可以共享一个数据缓冲区。在所有这些测试都需要查找特定的引用;因此您仍然需要获取某种类型的引用列表。看
locals()
?,globals()
。对于未命名的引用,比如数组列表,或者一些用户定义的字典呢?在Ipython运行示例:
一些变量和引用:
比较
^{pr2}$id
:除了
id
,其他人都没有共享id
。在我不想分享我的记忆。在
就在这个简短的会议上,我有76个项目在
locals()
。但我可以在它中搜索匹配id
与:其他测试也一样。在
我可以用同样的方法搜索
ll
:我可以在
locals()
搜索中添加一个层,方法是测试一个条目是否是一个列表或字典,并在其中进行搜索。在因此,即使我们确定了测试方法,搜索所有可能的引用也并非易事。在
我认为最好的方法是了解自己对变量的使用,这样就可以清楚地识别引用、视图和副本。在选定的情况下,您可以执行
may_share_memory
或比较数据缓冲区之类的测试。但目前还没有一种廉价的、确定的测试方法。当有疑问时,复印比冒着写东西的风险要便宜。在我使用numpy
的这些年里,我从来没有觉得有必要对这个问题给出一个明确的答案。在我觉得
OWNDATA
标志没有什么用处。考虑上述变量虽然我可以在这些简单的情况下预测
OWNDATA
值,但它的值并没有说明共享内存或共享id。False
表示它是从另一个数组创建的,因此可能共享内存。但那只是个“五月”。在我经常通过重塑一个范围来创建一个示例数组。在
显然没有其他数据引用,但是经过整形的数组并不“拥有”自己的数据。同样的情况也会发生
我不得不这么做
使
OWNDATA
为真。FalseOWNDATA
表示在创建新数组对象之后的某个内容,但是如果原始引用被重新定义或删除,则它不会改变。它很容易过时。在相关问题 更多 >
编程相关推荐