比较两个numpy数组的对象ID

比较两个numpy数组的对象ID

本文介绍了比较两个numpy数组的对象ID的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经使用numpy已有一段时间了,但是偶然发现了我不完全了解的一件事:

I have been using numpy for quite a while but I stumbled upon one thing that I didn't understand fully:

a = np.ones(20)
b = np.zeros(10)

print(id(a)==id(b))          # prints False
print(id(a), id(b))          # prints (4591424976, 4590843504)

print(id(a[0])==id(b[0]))    # prints True
print(id(a[0]), id(b[0]))    # prints (4588947064, 4588947064)

print(id(a[0]))              # 4588947184
print(id(b[0]))              # 4588947280

有人可以解释一下最近四个打印语句中观察到的行为吗?另外,我知道id为您提供了实际上在内存中分配的唯一对象id的事实,但是每次我运行最后两个print语句时,我都会得到不同的id值.这是预期的行为吗?

Can someone please explain the behavior observed in last four print statements? Also, I was aware of the fact that id gives you unique object id actually allocated in the memory but every time I run the last two print statements, I got different id values. Is this the expected behavior?

推荐答案

简短的答案是,您应该忘记依赖id来尝试深入了解python的工作原理.其输出受cpython实现细节,窥孔优化和内存重用的影响. id通常是红色鲱鱼.对于numpy尤其如此.

The short answer is that you should forget about relying on id to try and gain deep insight into the workings of python. Its output is affected by cpython implementation details, peephole optimizations and memory reuse. More often than not id is a red herring. This is especially true with numpy.

在您的特定情况下,只有ab作为python对象存在.当采用元素a[0]时,您将实例化一个新的python对象,其类型为numpy.float64(或者根据您的系统,可能为numpy.float32)的标量.这些是新的python对象,因此被赋予了新的id ,除非解释器意识到您尝试两次使用此对象(这可能是您的中间示例中发生的事情,尽管我这样做了)令人惊讶的是,两个具有不同值的numpy.float64对象被赋予相同的id.但是,如果先为专有名称分配a[0]b[0],这怪异的魔法就消失了,所以这可能是由于某些优化所致.内存地址也有可能被解释器重用,从而为您提供了以前出现过的id.

In your specific case only a and b exist as python objects. When you take an element, a[0], you instantiate a new python object, a scalar of type numpy.float64 (or maybe numpy.float32 depending on your system). These are new python objects and are thus given a new id, unless the interpreter realizes that you're trying to use this object twice (this is probably what's happening in your middle example, although I do find it surprising that two numpy.float64 objects with different values are given the same id. But the weird magic goes away if you assign a[0] and b[0] to proper names first, so this is probably due to some optimization). It could also happen that memory addresses get reused by the interpreter, giving you ids that have appeared before.

仅查看numpy的id是多么毫无意义,即使琐碎的视图也是具有新的id的新python对象,即使它们在所有目的和用途上都与原始的一样好.

Just to see how pointless id is with numpy, even trivial views are new python objects with new ids, even though for all intents and purposes they are as good as the original:

>>> arr = np.arange(3)

>>> id(arr)
140649669302992

>>> id(arr[...])
140649669667056

这是id在交互式shell中重用的示例:

And here's an example for id reuse in an interactive shell:

>>> id(np.arange(3))
140649669027120

>>> id(np.arange(3))
140649669028480

>>> id(np.arange(3))
140649669026480

对于numpy数组,肯定没有 int interning 这样的东西,所以以上内容仅是由于解释器造成的重用id s. id返回一个内存地址的事实再次只是一个cpython实现细节.忘了id.

Surely there's no such thing as int interning for numpy arrays, so the above is only due to the interpreter reusing ids. The fact that id returns a memory address is again just a cpython implementation detail. Forget about id.

您唯一想与numpy一起使用的是 numpy.may_share_memory numpy.shares_memory .

The only thing you might want to use with numpy is numpy.may_share_memory and numpy.shares_memory.

这篇关于比较两个numpy数组的对象ID的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-14 11:12