如何用Pandas针对重复Class列的行,按Length条件修改字段?
Pandas处理重复Class列的行修改方案
需求回顾
针对包含重复Class值的行,需执行以下逻辑:
- 所有重复行的
Head Teacher统一替换为该Class组内Length最长行的对应值;若组内Length全部相同,则取组内第一行的Head Teacher - 仅保留
Class组内Length最长行(若长度全相同则保留第一行)的Premium Course为Yes,其余行清空该字段 - 无重复的
Class行保持原样
实现步骤(矢量化操作,无循环)
1. 给Length列映射排序权重
因为Length是文本型的Short/Medium/Long,无法直接排序,先转为数值权重:
# 定义长度优先级映射 length_order = {'Short': 1, 'Medium': 2, 'Long': 3} df['Length_Weight'] = df['Length'].map(length_order)
2. 按Class分组计算目标值
通过groupby+transform实现组内逻辑,避免循环:
import pandas as pd # 计算每个Class组内的最大Length权重 max_weight = df.groupby('Class')['Length_Weight'].transform('max') # 标记哪些行是组内的"保留行"(最长Length,若全相同则取第一行) df['is_keep'] = (df['Length_Weight'] == max_weight) # 当组内所有Length相同时,仅保留第一行 df['is_keep'] = df.groupby('Class')['is_keep'].transform( lambda x: x.cummax() if x.all() else x ) # 获取每个Class组对应的目标Head Teacher teacher_map = df[df['is_keep']].set_index('Class')['Head Teacher'] df['Head Teacher'] = df['Class'].map(teacher_map) # 处理Premium Course字段:仅保留行设为Yes,其余清空 df['Premium Course'] = df['is_keep'].apply(lambda x: 'Yes' if x else '')
3. 清理临时列
df = df.drop(['Length_Weight', 'is_keep'], axis=1)
处理后结果
Class Length Head Teacher Premium Course 0 Maths Medium Mr. Bloggs Yes 1 English Short Mrs. Green 2 English Long Mrs. Green Yes 3 English Medium Mrs. Green 4 Science Long Mrs. Blue Yes 5 Science Long Mrs. Blue
关键逻辑说明
- 用
transform实现组内计算,确保每行都能获取组内的最大权重,这是矢量化操作的核心,避免了逐行循环 - 通过
cummax()处理组内Length全相同的情况,只保留第一行的is_keep为True - 利用映射(
map)快速替换Head Teacher,比循环赋值高效得多
内容的提问来源于stack exchange,提问作者Steven
相关产品推荐
相关产品推荐

