我有傻瓜。 python中的字典:
OrderedDict([(30, ('A1', 55.0)), (31, ('A2', 125.0)), (32, ('A3', 180.0)), (43, ('A4', nan))])
是否可以删除任何值为NaN的条目?我尝试过:
{k: dict_cg[k] for k in dict_cg.values() if not np.isnan(k)}
如果soln同时适用于python 2和python 3,那就太好了
答案 0 :(得分:5)
由于您拥有熊猫,因此可以在此处利用熊猫的pd.Series.notnull
函数,该函数可用于混合dtypes。
>>> import pandas as pd
>>> {k: v for k, v in dict_cg.items() if pd.Series(v).notna().all()}
{30: ('A1', 55.0), 31: ('A2', 125.0), 32: ('A3', 180.0)}
这不是答案的一部分,但可以帮助您了解我如何得出解决方案。尝试直接使用pd.notnull
解决此问题时,我遇到了一些奇怪的行为。
以dict_cg[43]
。
>>> dict_cg[43]
('A4', nan)
pd.notnull
不起作用。
>>> pd.notnull(dict_cg[43])
True
它将元组视为单个值(而不是值的可迭代)。此外,将其转换为列表然后进行测试也会给出错误的答案。
>>> pd.notnull(list(dict_cg[43]))
array([ True, True])
由于第二个值是nan
,所以我要查找的结果应该是[True, False]
。预转换为系列后,它终于可以工作了:
>>> pd.Series(dict_cg[43]).notnull()
0 True
1 False
dtype: bool
因此,解决方案是对其进行序列化,然后测试值。
沿着相似的路线,另一种(公认的环形交叉路)解决方案是预先转换为object
dtype numpy数组,而pd.notnull
将直接起作用:
>>> pd.notnull(np.array(dict_cg[43], dtype=object))
Out[151]: array([True, False])
我想像pd.notnull
直接将dict_cg[43]
转换为幕后的字符串数组,将NaN呈现为字符串“ nan”,因此不再是“ null”值。
答案 1 :(得分:4)
这应该有效:
for k,v in dict_cg.items():
if np.isnan(v[1]):
dict_cg.pop(k)
print dict_cg
输出:
OrderedDict([(30, ('A1', 55.0)), (31, ('A2', 125.0)), (32, ('A3', 180.0))])
答案 2 :(得分:2)
user308827,
问题中的代码似乎混淆了键和值,而忽略了值是元组这一事实。这是一个使用std libs和dict comprehension在python 2,3中工作的内衬:
from collections import OrderedDict
import math
od = OrderedDict([(30, ('A1', 55.0)), (31, ('A2', 125.0)), (32, ('A3', 180.0)), (43, ('A4', float('Nan')))])
no_nans = OrderedDict({k:v for k, v in od.items() if not math.isnan(v[1])})
# OrderedDict([(30, ('A1', 55.0)), (31, ('A2', 125.0)), (32, ('A3', 180.0))])
答案 3 :(得分:1)
您的原始代码实际上没有pandas
,并且仅出于过滤NaN的目的导入它似乎过多。但是,您的代码使用的是numpy
(np
)。
假设您的第一行应显示为:
dict_cg = OrderedDict([(30, ('A1', 55.0)), (31, ('A2', 125.0)), (32, ('A3', 180.0)), (43, ('A4', np.nan))])
尽管需要导入默认库numbers
,但此行接近于您所能使用的行:
OrderedDict([(k, vs) for k, vs in d.items() if not any ([isinstance(v, numbers.Number) and np.isnan(v) for v in vs])])
这样,您不需要pandas
,结果仍然是OrderedDict(就像以前一样),并且由于{{1 }}从左到右进行评估。