Python/Spyder基于列条件清洗DataFrame:统一同Ticket的Policy值
Pandas实现同Ticket下Policy字段统一标准化
你不需要写逐行迭代的if条件判断,用pandas自带的分组逻辑就能高效实现需求,以下是两种可直接运行的可行方案:
前置准备:导入依赖、构造原始数据
首先导入pandas库,复现你给出的原始数据集:
import pandas as pd import numpy as np # 构造原始DataFrame df = pd.DataFrame({ 'Year-Week': ['2022-25', '2022-26', '2022-20', '2022-15', '2022-26', '2022-24', '2022-26', '2022-25'], 'Ticket': [12502, 12502, 12502, 12502, 12471, 12409, 12409, 12406], 'Policy': ['COMPLIED', 'NOT COMPLIED', 'COMPLIED', 'COMPLIED', 'COMPLIED', 'COMPLIED', 'NOT COMPLIED', 'COMPLIED'] })
方法1:分组广播判断(推荐,代码最简洁)
利用groupby+transform的特性,按Ticket分组后直接把每组的判断结果广播到组内所有行,全程向量化运算无循环:
# 标记每个Ticket分组下是否存在任意一条"NOT COMPLIED"记录 non_complied_flag = df.groupby('Ticket')['Policy'].transform( lambda col: col.eq('NOT COMPLIED').any() ) # 统一给Policy字段赋值 df['Policy'] = np.where(non_complied_flag, 'NOT COMPLIED', 'COMPLIED')
运行后输出的结果和你给出的期望样例完全一致。
方法2:聚合映射(适合超大数据集,性能最优)
先分组聚合得到每个Ticket对应的最终Policy值,生成映射字典后再匹配回原表,千万级数据量下运行速度更快:
# 聚合计算每个Ticket的统一Policy取值 ticket_status = df.groupby('Ticket')['Policy'].agg( lambda col: 'NOT COMPLIED' if col.eq('NOT COMPLIED').any() else 'COMPLIED' ).to_dict() # 按Ticket映射取值覆盖原Policy字段 df['Policy'] = df['Ticket'].map(ticket_status)
注意:不要使用
iterrows、逐行apply写if判断的实现方式,上述两种方法都是pandas底层优化过的实现,运行效率比逐行循环高10~100倍,数据量越大性能差距越明显。
内容的提问来源于stack exchange,提问作者exenlediatán
相关产品推荐
相关产品推荐

