如何在Pandas中映射提取的邮箱至原DataFrame并保留无邮箱行?
解决方案:正确提取嵌套结构中的邮箱并映射回原列
问题分析
你的代码错误核心在于**mail函数遍历了整个df['metadata.to']列**,而非处理当前传入的单行数据,导致每一行都返回所有行的邮箱集合。使用apply时未正确接收行参数,也会引发同样问题。
修正后的代码
先保留NaN转'Null'的操作,再修改mail函数仅处理当前行数据:
import numpy as np import pandas as pd # 模拟你的原始数据 data = [ np.nan, [{'raw': '"Kate Grape"', 'email': 'green@grapes.com', 'firstName': 'Kate', 'lastName': 'Grape'}], [{'raw': '"Blue Sky"', 'email': 'white@clouds.com'}], [{'raw': '"Cement Block"', 'email': 'concrete@cement.com', 'firstName': 'Cement', 'lastName': 'Block'}], np.nan, np.nan, np.nan, [{'raw': '"Sahara Desert"', 'email': 'nowater@dusty.com', 'firstName': 'Sahara', 'lastName': 'Desert'}], np.nan ] df = pd.DataFrame({'metadata.to': data}) # 第一步:将NaN替换为'Null' df['metadata.to'] = df['metadata.to'].replace({np.nan: 'Null'}) # 修正后的mail函数:仅处理当前行的传入数据 def mail(data): emails = [] if data == 'Null': return emails # 无邮箱时返回空列表,若需保留'Null'可改为return 'Null' else: for item in data: # 防护:避免部分字典缺失'email'键引发报错 if 'email' in item: emails.append(item['email']) return emails # 用apply映射到每一行 df['metadata.to'] = df['metadata.to'].apply(mail)
代码说明
- 逻辑修正:
mail函数仅处理传入的data(当前行的'metadata.to'值),不再遍历整个列,确保每行只返回自身的邮箱列表。 - 异常防护:增加
if 'email' in item判断,避免部分嵌套字典缺失'email'键时触发KeyError。 - 空值处理:原NaN转成'Null'的行返回空列表,若需保留'Null'标识,可将
return emails改为return 'Null'。
最终效果
处理后的df['metadata.to']列输出如下:
0 [] 1 [green@grapes.com] 2 [white@clouds.com] 3 [concrete@cement.com] 4 [] 5 [] 6 [] 7 [nowater@dusty.com] 8 [] Name: metadata.to, dtype: object
内容的提问来源于stack exchange,提问作者shr2936
相关产品推荐
相关产品推荐

