【问题标题】:More efficient way to deal with KeyError from dictionary处理字典中的 KeyError 的更有效方法
【发布时间】:2020-11-04 16:02:55
【问题描述】:

我想使用 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'```

【问题讨论】:

  • 您能否添加完整的Traceback 消息以及您的DataFrame 的样例(可能显示df.head() 的输出?另外,您的DataFrame 的名称似乎发生了变化在这段代码中。不清楚这是否是一个错字。
  • 问题标题与内容不符,能否提供样例输入输出?也许是一些小的完整代码sn-p?
  • 看来问题一定出在您的 countries.get() 函数中。你能提供代码吗?

标签: python


【解决方案1】:

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))

【讨论】:

  • 谢谢!我确实尝试过 'try .. except' 但它给我带来了另一个错误。
  • 作为另一个问题发布!我们可以整晚都这样做。
【解决方案2】:

这个 James Tollefson 的答案,缩小到其核心,不想过多地改变他的答案,这里是实现:

def get_country_name(x: str) -> str:
    return countries[x][0] if countries.get(x) else 'unknown'
    
df['country_name'] = df['country'].apply(get_country_name)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-19
    • 2022-11-27
    • 2013-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-05
    相关资源
    最近更新 更多