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

我有一个包含值的列表,其中一个值是“ 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''
351824 次浏览

问题变了,答案也变了:

字符串不能使用 math.isnan进行测试,因为这需要浮点参数。在 countries列表中,有浮点数和字符串。

在你的情况下,以下内容就足够了:

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

旧答案

countries列表中,字面 'nan'是一个字符串,而不是等价于:

float('NaN')

在你的情况下,以下内容就足够了:

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

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

像这样:

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

使用 numpy 奇特的索引:

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


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

我注意到,比如熊猫会返回“ 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)

问题来自于 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''

但是熊猫版 pd.isnull()适用于数值和字符串值:

import pandas as pd
pd.isnull("A")
> False


pd.isnull(3)
> False


pd.isnull(np.nan)
> True


pd.isnull(None)
> True
import numpy as np


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

当然,我假设这里不是一个字符串,而是实际的 NaN (np.nan)。

用你的例子..。

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

由于 nan 不等于 nan (nan != nan)和 countries[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]

如果检查元素类型

type(countries[1])

结果是 <class float> 所以你可以使用以下代码:

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

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

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

另一种方法是像这样使用 过滤器:

countries = list(filter(lambda x: str(x) != 'nan', countries))

直接去除 nan 值的一种方法是:

import numpy as np
countries.remove(np.nan)

从范围列表中排除0

['ret'+str(x) for x in list(range(-120,241,5)) if (x!=0) ]

在我看来,所建议的大多数解决方案都没有考虑到业绩。如果你的列表有很多值,循环寻找和列表内涵就不是有效的解决方案。 下面的解决方案在计算时间方面更有效,并且它不假设您的列表具有数字或字符串。

import numpy as np
import pandas as pd
list_var = [np.nan, 4, np.nan, 20,3, 'test']
df = pd.DataFrame({'list_values':list_var})
list_var2 = list(df['list_values'].dropna())
print("\n* list_var2 = {}".format(list_var2))

如果您有一个不同类型的项目列表,并且希望过滤掉 NaN,您可以执行以下操作:

import math
lst = [1.1, 2, 'string', float('nan'), {'di':'ct'}, {'set'}, (3, 4), ['li', 5]]
filtered_lst = [x for x in lst if not (isinstance(x, float) and math.isnan(x))]

产出:

[1.1, 2, 'string', {'di': 'ct'}, {'set'}, (3, 4), ['li', 5]]
import numpy as np
countries=[x for x in countries if x is not np.nan]