Pandas遍历字典列表列提取首个字典id赋值新列报错求解
问题原因分析
- 报错的核心原因是
df_elem['sites']列中存在NaN缺失值:Pandas中空值默认是float类型的np.nan,你写的循环没有判断这种情况,当遍历到值为NaN的行时,执行for dicts in lists逻辑就会触发「float object not iterable」错误。你能打印出部分locations值是因为代码在运行到含NaN的行之前,处理正常行时的输出,报错是在后面执行到异常行时才触发的。 - 额外的逻辑缺陷:你现在的嵌套循环会遍历行内列表的所有字典,如果一行有多个字典(比如你示例里有一行3个字典的情况),最终赋值的是最后一个字典的id,不符合你「取第一个字典id」的需求。
正确实现代码
以下是符合函数式编程习惯的实现方案,无需使用explode方法:
import numpy as np def extract_first_site_id(x): # 排除非列表类的异常值(如NaN空值) if not isinstance(x, list): return np.nan # 列表非空则取第一个字典的id,空列表返回空值 return x[0].get('id') if len(x) > 0 else np.nan df_elem['location'] = df_elem['sites'].apply(extract_first_site_id)
如果你需要保留循环写法,修正后的版本如下:
import numpy as np # 先初始化新列默认值为空 df_elem['location'] = np.nan for row_idx, site_list in enumerate(df_elem['sites']): # 跳过空值等非列表的异常行 if not isinstance(site_list, list): continue # 仅当列表非空时取第一个字典的id赋值 if len(site_list) > 0: df_elem.loc[row_idx, 'location'] = site_list[0].get('id')
补充说明
两种实现都覆盖了三类边界场景:行值为NaN空值、行值为空列表、行值为含多个字典的列表,完全符合取第一个字典id的需求。基于apply的函数式写法逻辑封装更清晰,也更适配Pandas的使用习惯。
内容的提问来源于stack exchange,提问作者BryArk
相关产品推荐
相关产品推荐

