微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么itertools.groupby可以在列表中而不是在numpy数组中对NaN进行分组

如何解决为什么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在alistnananumpy.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)

当我遍历列表时,连续的nans被分组:

>>> 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'>

但是,如果我使用数组,则会将连续的nans放在不同的组中:

>>> 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 举报,一经查实,本站将立刻删除。