繁体   English   中英

从具有 None 元素的列表中获取最大值

[英]Getting max value from a list with None elements

我正在尝试使用以下代码从包含 nonetype 的列表对象中获取最大值:

import numpy as np

LIST = [1,2,3,4,5,None]
np.nanmax(LIST)

但我收到此错误消息

'>=' not supported between instances of 'int' and 'NoneType'

显然np.nanmax()不适用于None 从包含None值的列表对象中获取最大值的替代方法是什么?

一种方法可能是-

max([i for i in LIST if i is not None])

样品运行 -

In [184]: LIST = [1,2,3,4,5,None]

In [185]: max([i for i in LIST if i is not None])
Out[185]: 5

In [186]: LIST = [1,2,3,4,5,None, 6, 9]

In [187]: max([i for i in LIST if i is not None])
Out[187]: 9

根据comments from OP ,似乎我们可以有一个包含所有None的输入列表,对于这种特殊情况,它的输出应该是[None, None, None] 对于其他情况,输出将是标量max 所以,为了解决这种情况,我们可以这样做 -

a = [i for i in LIST if i is not None]
out = [None]*3 if len(a)==0 else max(a)

首先,转换为 numpy 数组。 指定dtype=np.floatX ,所有这些None将被转换为np.nan类型。

import numpy as np

lst = [1, 2, 3, 4, 5, None]

x = np.array(lst, dtype=np.float64)
print(x)
array([  1.,   2.,   3.,   4.,   5.,  nan])

现在,调用np.nanmax

print(np.nanmax(x))
5.0

要将最大值作为整数返回,您可以使用.astype

print(np.nanmax(x).astype(int)) # or int(np.nanmax(x))
5

此方法适用于v1.13.1

在 Python 2 中

max([i for i in LIST if i is not None])

Python 3 以后的简单

max(filter(None.__ne__, LIST))

或者更详细

max(filter(lambda v: v is not None, LIST))

您可以使用简单的列表理解来首先过滤掉无:

np.nanmax([x for x in LIST if x is not None])

这是我会做的:

>>> max(el for el in LIST if el is not None)
5

它表面上与其他答案相似,但有细微的不同,因为它使用生成器表达式而不是列表理解 不同之处在于它不创建中间列表来存储过滤结果。

使用过滤器去除所有的NoneLIST
我们利用了这样一个事实,即 filter 方法需要两个参数。 第一个是函数,第二个是 Iterable。
此函数必须返回从 Iterable 中删除的 Iterable 元素(作为第二个参数提供)。 我们将 None 作为第一个参数传递,因此 Iterable ( LIST ) 的所有false (在本例中为None ) 的对象都被过滤掉了。

import numpy as np
LIST = [1,2,3,4,5,None]

filtered_list = list(filter(None, LIST))
np.nanmax(filtered_list) 

编辑:这不会从列表中删除 0

filtered_list = list(filter(None.__ne__, LIST))

如果你想更具体地只取max数字,你可以使用filter数字抽象基类:

>>> import numbers
>>> filter(lambda e: isinstance(e, numbers.Number), [1,'1',2,None])
[1, 2]

或者,这个的生成器版本:

>>> max(e for e in [1,'1',2,None] if isinstance(e, numbers.Number))
2

由于这是 Python 3,您的错误是 Python 3 下更严格的比较规则:

Python 3.6.1 (default, Mar 23 2017, 16:49:06) 
[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.42.1)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 1<None
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: '<' not supported between instances of 'int' and 'NoneType'

Python 2 允许不同对象比较的地方:

Python 2.7.13 (default, Jan 15 2017, 08:44:24) 
[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.42.1)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 1<None
False
>>> 1>None
True

因此,当您创建一个 numpy 数组时,您将获得一个 Python 对象数组:

>>> np.array([1,2,3,4,5,None])
array([1, 2, 3, 4, 5, None], dtype=object)

所以 numpy 使用底层的 Python 3 比较规则来比较一个 Python 对象数组,这是你的错误:

>>> np.max(np.array([1,2,3,4,5,None]))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.6/site-packages/numpy/core/fromnumeric.py", line 2252, in amax
    out=out, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/numpy/core/_methods.py", line 26, in _amax
    return umr_maximum(a, axis, None, out, keepdims)
TypeError: '>=' not supported between instances of 'int' and 'NoneType'

因此,您需要在创建 numpy 数组时过滤掉None

>>> np.max(np.array([e for e in [1,2,3,4,5,None] if e is not None]))
5

或者将其转换为支持nan的 numpy 类型(并且np.int没有nan ):

>>> np.array([1,2,3,4,5,None], dtype=np.float)
array([  1.,   2.,   3.,   4.,   5.,  nan])

但在这种情况下, nan是最大值:

>>> np.max(np.array([1,2,3,4,5,None], dtype=np.float))
nan

所以使用np.nanmax

>>> np.nanmax(np.array([1,2,3,4,5,None], dtype=np.float))
5.0

Pandas DataFrame 有自己的功能,

list.idxmax()通过忽略 NaN 值返回最大值的索引。 查看此 URl以获取更多信息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM