You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用map、Lambda和切片查询字典时如何处理KeyError问题?

如何处理字典映射时的缺失键问题

操作背景

我从静态电子表格创建查找表/字典,用于后续输入数据的标注,并添加名为label的新字段:

import pandas as pd

lookup_table_data = pd.read_csv(r'C:\Location\format1.csv', sep=',')
lookup_table_data['label'] = 'apache'

随后生成字典:

my_format = lookup_table_data.set_index('server').T.to_dict('list')
print(my_format)

# 输出结果
{'ABC123': ['IBM', 1000, 'East Coast', 'apache'],
 'ABC456': ['Dell', 800, 'West Coast', 'apache'],
 'XYZ123': ['HP', 900, 'West Coast', 'apache']}

读取输入数据:

my_data = pd.read_csv(r'C:\Location\my_data.csv')
print(my_data)

# 输出结果
   server  busy       datetime
0  ABC123   24%  6/1/2024 0:02
1  ABC456   45%  6/1/2024 4:01
2  GHI100   95%  6/1/2024 9:10

遇到的问题

当尝试通过切片方法标注字段时,因输入数据中存在不在字典内的server(GHI100),出现KeyError:

my_data['type'] = my_data['server'].map(lambda x: my_format[x][0])
my_data['cost'] = my_data['server'].map(lambda x: my_format[x][1])
my_data['location'] = my_data['server'].map(lambda x: my_format[x][2])

# 报错信息
KeyError: 'GHI100'

移除GHI100数据后代码可正常运行:

server %busy       datetime  type  cost    location
   0  ABC123   24%  6/1/2024 0:02   IBM  1000  East Coast
   1  ABC456   45%  6/1/2024 4:01  Dell   800  West Coast

尝试使用.get()方法设置默认值时,若直接索引会出现“Index out of list range”;若仅获取字典值,则会把整个列表存入字段,不符合需求:

my_data['type'] = my_data['server'].map(lambda x: my_format.get(x, None))

结果:

server %busy       datetime                    type
0  ABC123   24%  6/1/2024 0:02   [IBM, 1000, East Coast]
1  ABC456   45%  6/1/2024 4:01   [Dell, 800, West Coast]
2  GHI100   95%  6/1/2024 9:10                      None

目前只能通过内连接移除不在字典中的server数据,但希望找到更合适的解决方案。

解决方案

方法1:优化.get()方法,设置默认值列表

在.get()中返回一个与字典值长度一致的默认列表,避免索引越界,同时提取对应位置的元素:

# 为缺失的server返回包含None的默认列表,长度与字典值一致
my_data['type'] = my_data['server'].map(lambda x: my_format.get(x, [None, None, None, None])[0])
my_data['cost'] = my_data['server'].map(lambda x: my_format.get(x, [None, None, None, None])[1])
my_data['location'] = my_data['server'].map(lambda x: my_format.get(x, [None, None, None, None])[2])
my_data['label'] = my_data['server'].map(lambda x: my_format.get(x, [None, None, None, None])[3])

执行后结果:

server  busy       datetime   type    cost    location   label
0  ABC123   24%  6/1/2024 0:02    IBM  1000.0  East Coast  apache
1  ABC456   45%  6/1/2024 4:01   Dell   800.0  West Coast  apache
2  GHI100   95%  6/1/2024 9:10   None     NaN        None    None

方法2:使用DataFrame左连接(推荐)

将查找字典转回DataFrame,通过左连接合并输入数据,自动保留所有行并填充缺失值,代码更简洁易维护:

# 将字典转回DataFrame,指定列名
lookup_df = pd.DataFrame.from_dict(my_format, orient='index', columns=['type', 'cost', 'location', 'label'])
# 左连接,保留my_data的所有行
my_data = my_data.merge(lookup_df, left_on='server', right_index=True, how='left')

执行后结果与方法1一致,且无需重复编写map逻辑,后续字段变更时只需调整列名即可。

方法3:使用Series映射

将字典的每个字段单独转为Series,再进行映射,Series的map方法会自动将缺失键映射为NaN:

# 提取各字段的Series
type_series = pd.Series({k: v[0] for k, v in my_format.items()})
cost_series = pd.Series({k: v[1] for k, v in my_format.items()})
location_series = pd.Series({k: v[2] for k, v in my_format.items()})
label_series = pd.Series({k: v[3] for k, v in my_format.items()})

# 映射到my_data
my_data['type'] = my_data['server'].map(type_series)
my_data['cost'] = my_data['server'].map(cost_series)
my_data['location'] = my_data['server'].map(location_series)
my_data['label'] = my_data['server'].map(label_series)

内容的提问来源于stack exchange,提问作者Chester

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 13:43:19