如何从列表Python / NumPy中删除Nan


89

我有一个列出值的列表,我得到的值之一是“ nan”

countries= [nan, 'USA', 'UK', 'France']

我试图将其删除,但每次都会收到错误消息

cleanedList = [x for x in countries if (math.isnan(x) == True)]
TypeError: a float is required

当我尝试这个:

cleanedList = cities[np.logical_not(np.isnan(countries))]
cleanedList = cities[~np.isnan(countries)]

TypeError: ufunc 'isnan' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

4
看起来像字符串"nan",而不是实际的NaN值。
BrenBarn

1
是的,它是一个字符串。[如果x!='nan',则x为x的国家/地区]
MarshalSHI 2014年

4
if condition == True是不必要的,您总是可以这样做if condition
reem 2014年

到目前为止,没有提供令人满意的解决方案。我也有同样的问题。基本上,它不适用于字符串。因此,在您的情况下np.isnan('USA')将发送相同的错误消息。如果找到解决方案,我将上传它。
Yohan Obadia

Answers:


127

问题已经改变,所以有了答案:

不能使用测试字符串,math.isnan因为它需要一个float参数。在countries列表中,您有浮点数和字符串。

在您的情况下,满足以下条件即可:

cleanedList = [x for x in countries if str(x) != 'nan']

旧答案

在您的countries列表中,文字'nan'是不是Python float的字符串nan,它等效于:

float('NaN')

在您的情况下,满足以下条件即可:

cleanedList = [x for x in countries if x != 'nan']

1
从逻辑上讲,您说的是真的。但这对我没有效果。
user3001937 2014年

然后问题出在另一个区域,您给出的数组是字符串,该字符串math.isnan会自然而然地出现错误。

是的!当我打印输出时,我得到了:[nan,'USA','UK','France']
user3001937 2014年

1
@ user3001937我已经根据新信息更新了答案

2
张绍晨:它不是字符串,是浮点数。仔细查看更新后的答案;Lego Stormtroopr转换x为字符串,因此您可以进行比较。即使与相比,nan总是会返回false ,所以这是比较它的最简单方法。==nan
免费Monica Cellio 2014年

17

问题来自于np.isnan()不能正确处理字符串值的事实。例如,如果您这样做:

np.isnan("A")
TypeError: ufunc 'isnan' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

但是,pandas版本pd.isnull()适用于数字和字符串值:

pd.isnull("A")
> False

pd.isnull(3)
> False

pd.isnull(np.nan)
> True

pd.isnull(None)
> True

14

使用您的示例,其中...

countries= [nan, 'USA', 'UK', 'France']

由于nan不等于nan(nan!= nan)且country [0] = nan,因此应注意以下几点:

countries[0] == countries[0]
False

然而,

countries[1] == countries[1]
True
countries[2] == countries[2]
True
countries[3] == countries[3]
True

因此,以下应工作:

cleanedList = [x for x in countries if x == x]

1
这是唯一的答案,当您在字符串列表中包含float('nan')时
-kmundnic

12
import numpy as np

mylist = [3, 4, 5, np.nan]
l = [x for x in mylist if ~np.isnan(x)]

这应删除所有NaN。当然,我认为这里不是字符串,而是实际的NaN(np.nan)。


1
这给了我错误:TypeError:输入类型不支持ufunc'isnan',并且根据强制转换规则“ safe”,不能将输入安全地强制转换为任何受支持的类型
Zak Keirn

1
为什么不简单:x[~ np.isnan(x)]?无需在numpy中理解列表。当然,我假设x是一个numpy数组。
布埃

我假设x不会像问题所建议的那样是一个numpy数组。
Ajay Shah,

它将期望浮动。不会在带有字符串@ZakKeirn的列表上工作
Shirish Bajpai

5

使用numpy花式索引

In [29]: countries=np.asarray(countries)

In [30]: countries[countries!='nan']
Out[30]: 
array(['USA', 'UK', 'France'], 
      dtype='|S6')

5

如果您检查元素类型

type(countries[1])

结果将是,<class float> 因此您可以使用以下代码:

[i for i in countries if type(i) is not float]

4

我喜欢从这样的列表中删除缺失的值:

list_no_nan = [x for x in list_with_nan if pd.notnull(x)]

1

在您的示例'nan'中,字符串是一个字符串,而不是isnan()仅使用字符串进行检查

像这样:

cleanedList = [x for x in countries if x != 'nan']


-1

我注意到,例如,Pandas将为空白值返回“ nan”。由于它不是字符串,因此需要将其转换为一个字符串以进行匹配。例如:

ulist = df.column1.unique() #create a list from a column with Pandas which 
for loc in ulist:
    loc = str(loc)   #here 'nan' is converted to a string to compare with if
    if loc != 'nan':
        print(loc)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.