如何基于姓名匹配填充Python DataFrame中Service列的NaN值?
解决DataFrame按姓名填充Service列NaN的问题
首先需要注意:你提供的示例数据里的'NaN'是字符串类型,需要先转换为Pandas能识别的实际缺失值np.nan,否则无法用缺失值处理方法。
推荐方法:Pandas原生高效实现
不需要复杂的for循环或lambda,用Pandas的分组和映射就能快速完成,效率远高于循环:
步骤1:构建正确的DataFrame
import pandas as pd import numpy as np data = [['P, Carl', 'NaN'], ['P, Carl', 'Endocrinology'], ['P, Carl', 'NaN'], ['W, Kate', 'Neurology'], ['W, Kate', 'NaN'], ['V, John', 'NaN']] df = pd.DataFrame(data, columns=['Name', 'Service']) # 将字符串'NaN'转为实际缺失值 df['Service'] = df['Service'].replace('NaN', np.nan)
步骤2:填充缺失值
方式1:先构建姓名-服务映射再填充
# 提取每个姓名对应的第一个有效Service值(去重后) name_service_map = df.groupby('Name')['Service'].first().dropna() # 用映射填充NaN df['Service'] = df['Service'].fillna(df['Name'].map(name_service_map))
方式2:用transform直接分组填充
如果需要更紧凑的写法,可用transform结合lambda(这里的lambda仅辅助分组内填充,并非遍历每一行):
df['Service'] = df.groupby('Name')['Service'].transform( lambda group: group.fillna(group.dropna().iloc[0]) if not group.dropna().empty else group )
用for循环实现(不推荐,仅满足需求)
如果非要用for循环,思路是先建立姓名到有效服务的映射,再逐行填充:
# 第一步:构建姓名到有效Service的字典 service_map = {} for _, row in df.iterrows(): if pd.notna(row['Service']): service_map[row['Name']] = row['Service'] # 第二步:遍历每一行填充NaN for idx, row in df.iterrows(): if pd.isna(row['Service']) and row['Name'] in service_map: df.loc[idx, 'Service'] = service_map[row['Name']]
最终结果
处理后的DataFrame:
Name Service 0 P, Carl Endocrinology 1 P, Carl Endocrinology 2 P, Carl Endocrinology 3 W, Kate Neurology 4 W, Kate Neurology 5 V, John NaN
内容的提问来源于stack exchange,提问作者keeptrying
相关产品推荐
相关产品推荐

