首页 > 解决方案 > 处理字典中的 KeyError 的更有效方法

问题描述

我想使用 iso3166 包查找具有顶级域(例如“de”、“it”、“us”)的数据框列的国家/地区名称。数据集中存在 iso3166 中不存在的域,因此引发了值错误。我试图通过让代码返回布尔值来解决值错误,但它运行了很长时间。很高兴知道如何加快速度。

样本数据:df['country']

0    an
1    de
2    it

我的代码(注意代码不会引发 KeyError 错误。我的问题是如何让它更快)

df['country_name'] = df['country'].apply(lambda x: countries.get(x)[0] if \ 
    df['country'].str.find(x).any() == countries.get(x)[1].lower() else 'unknown')

df['country]是数据框列。countries.get()用于从 iso3166 获取国家名称

df['country'].str.find(x).any()查找顶级域并countries.get(x)[1].lower()返回顶级域。如果它们相同,那么我countries.get(x)[0]用来返回国家名称

预期产出

country country_name
an      unknown
de      Germany
it      Italy

运行时出错df['country_name'] = df['country'].apply(lambda x: countries.get(x)[0])(我重命名了数据框,因此它与错误消息不同)

KeyError                                  Traceback (most recent call last)
<ipython-input-110-d51176ce2978> in <module>
----> 1 bf['country_name'] = bf['country'].apply(lambda x: countries.get(x)[0])

/opt/anaconda3/lib/python3.8/site-packages/pandas/core/series.py in apply(self, func, convert_dtype, args, **kwds)
   3846             else:
   3847                 values = self.astype(object).values
-> 3848                 mapped = lib.map_infer(values, f, convert=convert_dtype)
   3849 
   3850         if len(mapped) and isinstance(mapped[0], Series):

pandas/_libs/lib.pyx in pandas._libs.lib.map_infer()

<ipython-input-110-d51176ce2978> in <lambda>(x)
----> 1 bf['country_name'] = bf['country'].apply(lambda x: countries.get(x)[0])

/opt/anaconda3/lib/python3.8/site-packages/iso3166/__init__.py in get(self, key, default)
    358 
    359         if r == NOT_FOUND:
--> 360             raise KeyError(key)
    361 
    362         return r

KeyError: 'an'```

标签: python

解决方案


一些错误处理和在apply()方法之外定义你的逻辑应该会让你到达你想去的地方。就像是:

def get_country_name(x):
    try:
        return countries.get(x)[0]
    except:
        return 'unknown'
    
df['country_name'] = df['country'].apply(lambda x: get_country_name(x))

推荐阅读