gpt4 book ai didi

python - 为什么 itertools.groupby 可以将 NaN 分组在列表中而不是在 numpy 数组中

转载 作者:太空狗 更新时间:2023-10-29 16:54:57 24 4
gpt4 key购买 nike

我很难调试一个问题,其中 list 中的 float nan 中的 nan numpy.arrayitertools.groupby 中使用时的处理方式不同:

给定以下列表和数组:

from itertools import groupby
import numpy as np

lst = [np.nan, np.nan, np.nan, 0.16, 1, 0.16, 0.9999, 0.0001, 0.16, 0.101, np.nan, 0.16]
arr = np.array(lst)

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

>>> 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 放在不同的组中:

>>> for key, group in groupby(arr):
... if np.isnan(key):
... print(key, list(group), 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, list(group), 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 进行分组?

最佳答案

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 解释为值序列( float 、整数等)的位和字节区域。

问题在于,当您要求 Python 迭代包含浮点值的 NumPy 数组时(在 for 循环或 groupby 级别),Python 需要将这些值装箱字节转换为适当的 Python 对象。它在迭代时为数组中的每个单个值在内存中创建一个全新的 Python 对象。

例如,您可以看到在调用 .tolist() 时为每个 nan 值创建了不同的对象:

>>> [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 能够对 Python 列表的 np.nan 进行分组,因为它在比较 Python 对象时首先检查 identity .因为这些指向 nan 的指针都指向同一个 np.nan 对象,所以分组是可能的。

但是,对 NumPy 数组的迭代不允许此初始身份检查成功,因此 Python 回退到检查相等性和 nan != nan 正如您所说。

关于python - 为什么 itertools.groupby 可以将 NaN 分组在列表中而不是在 numpy 数组中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41723419/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com