如何找到具有相同ID的所有变量? [英] How to find all variables with identical id?

查看:135
本文介绍了如何找到具有相同ID的所有变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们说我有一个 numpy的阵列 A 并创建 B 是这样的:

Let's say I have a numpy array a and create b like this:

a = np.arange(3)
b = a

如果我现在改 B 例如像这样

If I now change b e.g. like this

b[0] = 100

和印刷 A B ,其 ID .flags

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 B 看起来相同,它们的 ID 取值预期是一致的。

So, a and b look the same and their ids are identical as expected.

当我现在做同样的使用复制()

When I now do the same using 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 D 不同,所以做他们的 ID S;也符合市场预期。

In this case c and d differ and so do their ids; also as expected.

不过,混淆我的是我从 .flags 获得输出:在所有情况下, OWNDATA 设置到。当我阅读文档我发现:

However, what confuses me is the output I obtain from .flags: In all cases, OWNDATA is set to True. When I read the documentation, I find:

OWNDATA(O)数组拥有其占用的内存或借用其
  另一个对象。

OWNDATA (O) The array owns the memory it uses or borrows it from another object.

我的主要问题是现在:

什么是找到指向同一 ID的所有变量(在上面 A 和 b ),即检查与相同ID的另一个变量是否存在?我以为 OWNDATA 将是为帮助,但显然事实并非如此。

What would be the easiest way to find all variables that point to the same id (in the example above a and b) i.e. to check whether another variable with the same id exists? I thought OWNDATA would be of help for that but apparently it is not.

相关问题:

什么是 OWNDATA 实际用于,在这种情况下,为 OWNDATA 设置为

What is OWNDATA actually used for, in which case is OWNDATA set to False?

推荐答案

有2个问题 - 你怎么确定你要比较的变量,你该怎么办比较它们

There are 2 issues - how do you identify the variables that you want to compare, and how to do you compare them.

在第二个第一。

我的版本(1.8.2)不具有 np.shares_memory 功能。它有一个 np.may_share_memory

My version (1.8.2) does not have a np.shares_memory function. It does have a np.may_share_memory.

https://github.com/numpy/numpy/pull/6166 是,增加了拉入请求 shares_memory ;这是过时去年八月。所以,你得有全新的 numpy的来使用它。需要注意的是一个明确的测试可能是难,并且它可发出如太硬的错误消息。我想象,比如有一些切片共享内存,但很难通过简单的比较缓冲的出发点来识别。

https://github.com/numpy/numpy/pull/6166 is the pull request that adds shares_memory; it' dated last August. So you'd have to have brand new numpy to use it. Note that a definitive test is potentially hard, and it may issue as 'TOO HARD' error message. I imagine, for example that there are some slices that share the memory, but hard to identify by simply comparing buffer starting points.

<一个href=\"https://github.com/numpy/numpy/blob/97c35365beda55c6dead8c50df785eb857f843f0/numpy/core/tests/test_mem_overlap.py\" rel=\"nofollow\">https://github.com/numpy/numpy/blob/97c35365beda55c6dead8c50df785eb857f843f0/numpy/core/tests/test_mem_overlap.py对于这些 memory_overlap 功能单元测试。如果你想看看一个艰巨的任务,它要考虑所有已知的2阵列之间的可能的重叠情况看。

https://github.com/numpy/numpy/blob/97c35365beda55c6dead8c50df785eb857f843f0/numpy/core/tests/test_mem_overlap.py is the unit test for these memory_overlap functions. Read it if you want to see what a daunting task it is to think of all the possible overlap conditions between 2 known arrays.

我喜欢看阵列的 .__ array_interface __ 。在该词典的一个项目是数据,这是一个指向数据缓冲区。相同的指针指中的数据是共享的。但是,一个视图可能某个地方的路线开始。我也不会感到惊讶,如果 shares_memeory 看着这个指针。

I like to look at the array's .__array_interface__. One item in that dictionary is 'data', which is a pointer to the data buffer. Identical pointer means the data is shared. But a view might start somewhere down the line. I wouldn't be surprised if shares_memeory looks at this pointer.

相同的 ID 表示两个变量引用同一个对象,但不同的数组对象可以共享一个数据缓冲区。

Identical id means 2 variables reference the same object, but different array objects can share a data buffer.

所有这些测试需要看具体的参考;所以你仍然需要得到某种形式的参考名单。看看当地人()全局()。关于无名引用,如数组列表,或者一些用户定义的字典吗?

All these tests require looking specific references; so you still need to get some sort of list of references. Look at locals()?, globals(). What about unnamed references, such as list of arrays, or some user defined dictionary?

一个例子IPython中运行:

An example Ipython run:

有些变量和参考文献:

In [1]: a=np.arange(10)
In [2]: b=a           # reference
In [3]: c=a[:]        # view
In [4]: d=a.copy()    # copy
In [5]: e=a[2:]       # another view
In [6]: ll=[a, a[:], a[3:], a[[1,2,3]]]  # list 

比较 ID

In [7]: id(a)
Out[7]: 142453472
In [9]: id(b)
Out[9]: 142453472

其他的无共享 ID ,除了 LL [0]

In [10]: np.may_share_memory(a,b)
Out[10]: True
In [11]: np.may_share_memory(a,c)
Out[11]: True
In [12]: np.may_share_memory(a,d)
Out[12]: False
In [13]: np.may_share_memory(a,e)
Out[13]: True
In [14]: np.may_share_memory(a,ll[3])
Out[14]: False

这是对我的期望;意见共享内存,副本没有。

That's about what I'd expect; views share memory, copies do not.

In [15]: a.__array_interface__
Out[15]: 
{'version': 3,
 'data': (143173312, False),
 'typestr': '<i4',
 'descr': [('', '<i4')],
 'shape': (10,),
 'strides': None}
In [16]: a.__array_interface__['data']
Out[16]: (143173312, False)
In [17]: b.__array_interface__['data']
Out[17]: (143173312, False)
In [18]: c.__array_interface__['data']
Out[18]: (143173312, False)
In [19]: d.__array_interface__['data']
Out[19]: (151258096, False)            # copy - diff buffer
In [20]: e.__array_interface__['data'] 
Out[20]: (143173320, False)            # differs by 8 bytes
In [21]: ll[1].__array_interface__['data']
Out[21]: (143173312, False)            # same point

只是这短短的会议上,我甲肝在 76项当地人()。但是,我可以寻找它匹配 ID

Just with this short session I hav 76 items in locals(). But I can search it for matching id with:

In [26]: [(k,v) for k,v in locals().items() if id(v)==id(a)]
Out[26]: 
[('a', array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])),
 ('b', array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]))]

同为其他测试。

我可以用同样的方法搜索 LL

I can search ll in the same way:

In [28]: [n for n,l in enumerate(ll) if id(l)==id(a)]
Out[28]: [0]

如果一个项目是一个列表或字典,做内搜索,我可以添加一个图层到当地人()通过测试搜索。

因此​​,即使我们安定在测试方法,它是不平凡的,以搜寻所有可能的引用。

So even if we settle on the testing method, it isn't trivial to search for all possible references.

我认为最好的办法是只了解自己使用的变量,这样就可以清楚地标识引用,看法和副本。在选择的情况下,您可以执行如 may_share_memory 测试或比较databuffers。但没有一种廉价的,明确的测试。如果有疑问它是便宜了写东西,使副本,而不是风险。在我多年的 numpy的使用我从来没有觉得需要一个明确的回答这个问题。

I think the best approach is to just understand your own use of variables, so that you can clearly identify references, views and copies. In selected cases you can perform tests like may_share_memory or comparing databuffers. But there isn't an inexpensive, definitive test. When in doubt it is cheaper to make a copy, than to risk over writing something. In my years of numpy use I've never felt the need to an definitive answer to this question.

我没有找到 OWNDATA 标记非常有用的。考虑上述变量

I don't find the OWNDATA flag very useful. Consider the above variables

In [35]: a.flags['OWNDATA']
Out[35]: True
In [36]: b.flags['OWNDATA']   # ref
Out[36]: True
In [37]: c.flags['OWNDATA']   # view
Out[37]: False
In [38]: d.flags['OWNDATA']   # copy
Out[38]: True
In [39]: e.flags['OWNDATA']   # view
Out[39]: False

虽然我可以predict在这些简单的情况下, OWNDATA 价值,它的价值不说太多关于共享内存或共享ID。 表明,它是从另一个数组创建的,因此可以共享内存。但是,这只是一个'可能'。

While I can predict the OWNDATA value in these simple cases, its value doesn't say much about shared memory, or shared id. False suggests it was created from another array, and thus may share memory. But that's just a 'may'.

我经常被重塑了一系列创建一个简单的数组。

I often create a sample array by reshaping a range.

In [40]: np.arange(3).flags['OWNDATA']
Out[40]: True
In [41]: np.arange(4).reshape(2,2).flags['OWNDATA']
Out[41]: False

有显然没有其他的参照数据,但是重构阵列不'自己的'其自己的数据。同时将与发生

There's clearly no other reference to the data, but the reshaped array does not 'own' its own data. Same would happen with

temp = np.arange(4); temp = temp.reshape(2,2)

我不得不这样做。

I'd have to do

temp = np.arange(4); temp.shape = (2,2)

要保持 OWNDATA 真。假 OWNDATA 意味着什么创建新的数组对象之后,但如果原来的基准被重新定义或删除它不会改变。它很容易变得过时了。

to keep OWNDATA true. False OWNDATA means something right after creating the new array object, but it doesn't change if the original reference is redefined or deleted. It easily becomes out of date.

这篇关于如何找到具有相同ID的所有变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆