[英]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
它表面上與其他答案相似,但有細微的不同,因為它使用生成器表達式而不是列表理解。 不同之處在於它不創建中間列表來存儲過濾結果。
使用過濾器去除所有的None
的LIST
我們利用了這樣一個事實,即 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.