如何解决为什么itertools.groupby可以在列表中而不是在numpy数组中对NaN进行分组
python列表只是指向内存中对象的指针数组。特别是lst
持有指向对象的指针np.nan
:
>>> [id(x) for x in lst]
[139832272211880, # nan
139832272211880, # nan
139832272211880, # nan
139832133974296,
139832270325408,
139832133974296,
139832133974464,
139832133974320,
139832133974296,
139832133974440,
139832272211880, # nan
139832133974296]
(np.nan
在我的计算机上为139832272211880。)
另一方面,NumPy数组只是内存的连续区域;它们是位和字节的区域,被NumPy解释为一系列值(浮点数,整数等)。
问题在于,当您要求Python遍历具有浮动值(在for
-loop或groupby
级别)的NumPy数组时,Python需要将这些字节装箱到适当的Python对象中。迭代时,它将在内存中为数组中的每个单个值创建一个全新的Python对象。
例如,您可以看到nan
在.tolist()
调用时会为每个值创建不同的对象:
>>> [id(x) for x in arr.tolist()]
[4355054616, # nan
4355054640, # nan
4355054664, # nan
4355054688,
4355054712,
4355054736,
4355054760,
4355054784,
4355054808,
4355054832,
4355054856, # nan
4355054880]
itertools.groupby
能够分组以np.nan
获取python列表,因为它在比较Python对象时首先检查 身份
。因为这些指向nan
所有np.nan
对象的指针都指向同一对象,所以可以进行分组。
但是,通过NumPy数组进行迭代无法使此初始身份检查成功,因此Python会退回到检查是否相等以及nan != nan
您所说的那样。
解决方法
我很难调试一个问题,其中nan
在alist
和nan
anumpy.array
中使用float时,对它们的处理方式有所不同itertools.groupby
:
给定以下列表和数组:
from itertools import groupby
import numpy as np
lst = [np.nan,np.nan,0.16,1,0.9999,0.0001,0.101,0.16]
arr = np.array(lst)
当我遍历列表时,连续的nan
s被分组:
>>> for key,group in groupby(lst):
... if np.isnan(key):
... print(key,list(group),type(key))
nan [nan,nan,nan] <class 'float'>
nan [nan] <class 'float'>
但是,如果我使用数组,则会将连续的nan
s放在不同的组中:
>>> for key,group in groupby(arr):
... if np.isnan(key):
... print(key,type(key))
nan [nan] <class 'numpy.float64'>
nan [nan] <class 'numpy.float64'>
nan [nan] <class 'numpy.float64'>
nan [nan] <class 'numpy.float64'>
即使我将数组转换回列表:
>>> for key,group in groupby(arr.tolist()):
... if np.isnan(key):
... print(key,type(key))
nan [nan] <class 'float'>
nan [nan] <class 'float'>
nan [nan] <class 'float'>
nan [nan] <class 'float'>
我正在使用:
numpy 1.11.3
python 3.5
我知道一般来说nan != nan
,为什么这些操作会产生不同的结果?怎么可能将groupby
分组nan
?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。