我正在尝试使用以下代码从包含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
值的列表对象中获取最大值的替代方法是什么?
答案 0 :(得分:5)
首先,转换为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
。
答案 1 :(得分:2)
一种方法可能是 -
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)
答案 2 :(得分:1)
您可以使用简单的列表推导来首先过滤掉Nones:
np.nanmax([x for x in LIST if x is not None])
答案 3 :(得分:1)
使用filter删除None
的所有LIST
我们利用了这样一个事实:filter方法有两个参数。第一个是函数,第二个是Iterable
此函数必须返回Iterable的一个元素(作为第二个参数提供),该元素将从Iterable中删除。我们将None作为第一个参数传递,因此Iterable(None
)的所有对象 false (在本例中为LIST
)过滤掉了。
import numpy as np
LIST = [1,2,3,4,5,None]
filtered_list = list(filter(None, LIST))
np.nanmax(filtered_list)
修改:这不会从LIST中删除0
filtered_list = list(filter(None.__ne__, LIST))
答案 4 :(得分:1)
在python 2中
max([i for i in LIST if i is not None])
在python 3之后简单
max(filter(None, LIST))
但是,如果列表中有代码,则上面的代码也会过滤掉0。所以工作代码如下所示
max(filter(lambda v: v is not None, LIST))
答案 5 :(得分:1)
如果您想更具体地仅使用max
数字,您可以使用filter
和numbers抽象基类:
>>> 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
答案 6 :(得分:0)
以下是我要做的事情:
>>> max(el for el in LIST if el is not None)
5
它表面上与其他答案类似,但略有不同,因为它使用生成器表达式而不是列表理解。不同之处在于它没有创建一个中间列表来存储过滤结果。
答案 7 :(得分:0)
Pandas DataFrame具有自己的功能,
list.idxmax()
通过忽略NaN值来返回最大值的索引。
在this URl中查找更多信息。