Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python';s和Numpy';s nan和set_Python_Numpy_Set_Nan - Fatal编程技术网

Python';s和Numpy';s nan和set

Python';s和Numpy';s nan和set,python,numpy,set,nan,Python,Numpy,Set,Nan,我在Python的Numpy、set和NaN(非数字)中遇到了一种不可预测的行为: 这里np.nan生成一个元素集,而Numpy的nan在一个集中生成多个nan。浮动('nan')也是如此!请注意: >>> type(float('nan')) == type(np.nan) True 我想知道这种差异是如何产生的,以及不同行为背后的合理性是什么。NAN的特性之一就是NAN!=南,不像其他数字。但是,set的实现首先检查id(x)是否与哈希索引中的现有成员匹配,然后再尝试插入

我在Python的Numpy、set和NaN(非数字)中遇到了一种不可预测的行为:

这里np.nan生成一个元素集,而Numpy的nan在一个集中生成多个nan。浮动('nan')也是如此!请注意:

>>> type(float('nan')) == type(np.nan)
True

我想知道这种差异是如何产生的,以及不同行为背后的合理性是什么。

NAN的特性之一就是NAN!=南,不像其他数字。但是,
set
的实现首先检查id(x)是否与哈希索引中的现有成员匹配,然后再尝试插入新成员。如果有两个ID不同的对象都具有NAN值,那么在集合中会有两个条目。如果它们都有相同的id,则会折叠成一个条目


正如其他人所指出的,
np.nan
是一个始终具有相同id的单一对象。

它看起来像
numpy.nan
是一个单一对象。因此,它的每个实例都具有相同的标识。查看
id(np.nan)'v
id(np.float64('nan'))`(对于重复实例)。
[id(np.float64('nan')表示范围(10)中的n]
给出
[65159576、65159576、65159576、65159576、65159576、65159576、65159576、65159576、65159576、65159576]和
[id(np.nan)表示范围(10)]
给出了
[35133032、35133032、35133032、35133032、35133032、35133032、35133032、35133032、35133032、35133032]
@FinnÅrupNielsen在这种情况下创建的NAN对象每次都会被销毁,因为它是没有引用的临时对象,并且对象位置正在被重用。这就是为什么每次都会得到相同的id。@FinnÅrupNielsen对于我来说,numpy 1.8.0的结果不同,
[id(np.float64('nan'))是两个不同的id,用于范围(10)内的n]
。这是因为我们正在丢弃对象,因此CPython可以重用内存空间。尝试使用:
x=[np.float64('nan'),表示范围(10)中的n);[id(y)表示x中的y]
关于“始终具有相同的id”,有些事情是奇怪的:如果
l=np.array([np.nan,np.nan])
,那么
id(l[0])、id(l[1])、[id(x)表示l中的x]
(946651263888946651263888、[946651263888、[946651263912])
@fuglede这是一个很棒的评论!“有人知道为什么会这样吗?”episodeyang问得好。我希望x的
是一致的,要么给出实际对象的引用,要么制作副本。它似乎有一些我还没有弄明白的微妙之处。还要注意的是,不能保证后续调用
id(l[0])
会给出相同的结果,如果您使用
list(map(id,l))
而不是理解,您会得到重复的id(但是
list(map(id,list(l))
确实创建了一个副本); 阵列很有趣。这种行为并不特定于
np.nan
;比如说,整数也是一样的。整数的例子本身也很有趣,因为当使用低整数时,你得到的对象不一定是CPython维护的单例;比较np.array([2,2])中x的
[id(x)]
和[2,2]]中x的
[id(x)]
。因此,所有这一切实际上更多地说明了数组的行为,但它确实表明,您不能总是假设两个看起来都像
np.nan
的对象必然具有相同的
id
。特别是,在原始文章中提供的示例中,
set(np.array([np.nan,np.nan])
将给出一个两元素集。
>>> type(float('nan')) == type(np.nan)
True