如何不使用for循环基于条件填充DataFrame的Score列
用Pandas向量化操作实现DataFrame条件填充(无循环)
问题背景
现有两个Pandas DataFrame:
- df1:包含
FirstName、LastName、EducationLevel、Score列 - df2:包含部分df1的人员信息,列
A(姓名)、B(职业)、C(状态),无Score列,示例数据:
A B C Alex Student Due George Teacher Due Helen Student Overdue Maria Teacher Overdue
需要通过姓名匹配,按以下规则修改df1的Score列,要求不使用for循环,用Pandas向量化操作实现:
- df2中
B=Student且C=Due→ df1对应人员Score设为3 - df2中
B=Teacher且C=Due→ df1对应人员Score设为5 - df2中
B=Student且C=Overdue→ df1对应人员Score设为2 - df2中
B=Teacher且C=Overdue→ df1对应人员Score设为1
解决方案
步骤1:为df2生成对应Score值
先将df2的职业(B)和状态(C)组合映射到目标Score,这里提供两种向量化实现方式:
方式1:字典映射(直观易维护)
import pandas as pd # 定义规则字典,键为(B,C)组合,值为对应Score score_rule = { ('Student', 'Due'): 3, ('Teacher', 'Due'): 5, ('Student', 'Overdue'): 2, ('Teacher', 'Overdue'): 1 } # 为df2添加Score列,直接映射规则 df2['Score'] = df2.apply(lambda row: score_rule[(row['B'], row['C'])], axis=1)
方式2:np.select(纯向量化,性能更优)
import pandas as pd import numpy as np # 定义条件列表 conditions = [ (df2['B'] == 'Student') & (df2['C'] == 'Due'), (df2['B'] == 'Teacher') & (df2['C'] == 'Due'), (df2['B'] == 'Student') & (df2['C'] == 'Overdue'), (df2['B'] == 'Teacher') & (df2['C'] == 'Overdue') ] # 对应条件的Score值列表 score_choices = [3, 5, 2, 1] # 生成df2的Score列 df2['Score'] = np.select(conditions, score_choices)
步骤2:将Score值匹配到df1
先把df2处理成「姓名-Score」的映射字典,再用map方法批量更新df1的Score:
情况1:df2的A列对应df1的FirstName
# 生成姓名到Score的字典 name_to_score = df2.set_index('A')['Score'].to_dict() # 批量更新df1的Score,未匹配到的人员保留原Score值 df1['Score'] = df1['FirstName'].map(name_to_score).fillna(df1['Score'])
情况2:df2的A列对应df1的「FirstName+LastName」
如果df1的姓名是由FirstName和LastName组合而成,先合并成完整姓名再匹配:
# 为df1生成完整姓名列 df1['FullName'] = df1['FirstName'] + ' ' + df1['LastName'] # 生成姓名到Score的字典 name_to_score = df2.set_index('A')['Score'].to_dict() # 批量更新Score,未匹配的保留原值 df1['Score'] = df1['FullName'].map(name_to_score).fillna(df1['Score']) # 可选:删除临时生成的FullName列 df1.drop('FullName', axis=1, inplace=True)
原理说明
- 上述操作全程使用Pandas/Numpy的向量化方法,避免了Python级别的for循环,处理大数据集时性能远高于循环实现。
map方法会自动匹配姓名,未找到匹配项时返回NaN,用fillna保留原Score值,确保不修改df1中不在df2里的人员数据。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

