【发布时间】:2017-06-03 02:29:57
【问题描述】:
Since we're on the topic of peculiarities surrounding numpy's nan,我发现了一些我也不明白的东西。我发布这个问题主要是作为 MSeifert 的延伸,因为我们的观察似乎有一个共同的原因。
早些时候,I posted a solution 涉及在包含 nan 值的序列上使用 itertools.groupby:
return max((sum(1 for _ in group) for key, group in groupby(sequence) if key is nan), default=0)
但是,我在上面链接的 MSeifert 的问题上看到了this answer,它显示了我可能制定此算法的另一种方法:
return max((sum(1 for _ in group) for key, group in groupby(sequence, np.isnan)), default=0)
实验
我已经使用列表和 numpy 数组测试了这两种变体。代码和结果如下:
from itertools import groupby
from numpy import nan
import numpy as np
def longest_nan_run(sequence):
return max((sum(1 for _ in group) for key, group in groupby(sequence) if key is nan), default=0)
def longest_nan_run_2(sequence):
return max((sum(1 for _ in group) for key, group in groupby(sequence, np.isnan)), default=0)
if __name__ == '__main__':
nan_list = [nan, nan, nan, 0.16, 1, 0.16, 0.9999, 0.0001, 0.16, 0.101, nan, 0.16]
nan_array = np.array(nan_list)
print(longest_nan_run(nan_list)) # 3 - correct
print(longest_nan_run_2(nan_list)) # 7 - incorrect
print(longest_nan_run(nan_array)) # 0 - incorrect
print(longest_nan_run_2(nan_array)) # 7 - incorrect
分析
- 在所有四种组合中,只有使用 original 函数检查 lists 才能正常工作。
-
modified 函数(使用
np.isnan)似乎对列表和数组都以相同的方式工作。 - 检查数组时,original函数似乎找不到任何
nan值。
谁能解释这些结果?同样,由于这个问题与 MSeifert 的问题有关,因此对他的结果的解释也可能解释我的问题(反之亦然)。
进一步调查
为了更好地了解正在发生的事情,我尝试打印出groupby 生成的组:
def longest_nan_run(sequence):
print(list(list(group) for key, group in groupby(sequence) if key is nan))
return max((sum(1 for _ in group) for key, group in groupby(sequence) if key is nan), default=0)
def longest_nan_run_2(sequence):
print(list(list(group) for _, group in groupby(sequence, np.isnan)))
return max((sum(1 for _ in group) for key, group in groupby(sequence, np.isnan)), default=0)
一个根本的区别(回想起来是有道理的)是原始函数(使用if key is nan)将过滤掉所有除了nan值,所以所有生成的组将仅包含 nan 值,如下所示:
[[nan, nan, nan], [nan]]
另一方面,modified 函数会将所有非nan 值分组到它们自己的组中,如下所示:
[[nan, nan, nan], [0.16, 1.0, 0.16, 0.99990000000000001, 0.0001, 0.16, 0.10100000000000001], [nan], [0.16]]
这解释了为什么修改后的函数在两种情况下都返回 7 - 它考虑值是“nan”或“不是nan”,并返回最长的连续序列。
这也意味着我对 groupby(sequence, keyfunc) 工作原理的假设是错误的,并且修改后的函数不是原始函数的可行替代方案。
不过,我仍然不确定在列表和数组上运行原始函数时结果的差异。
【问题讨论】:
标签: python arrays list numpy nan