Pandas:如何按规则替换DataFrame中列表型Holiday字段为单个值?
问题描述
原始DataFrame与期望输出如下:
import pandas as pd # 原始DataFrame df = pd.DataFrame({ 'index': [1, 2, 3, 4, 5, 6, 7], 'result': [80, 85, 90, 91, 92, 93, 94], 'holiday': ['Dam', 'Dam', 'Easter', ['Easter', 'TomTom'], ['TomTom', 'Christmas'], None, ['Birthday', 'Halloween']] }) # 期望输出的df_out df_out = pd.DataFrame({ 'index': [1, 2, 3, 4, 5, 6, 7], 'result': [80, 85, 90, 91, 92, 93, 94], 'holiday': ['Dam', 'Dam', 'Easter', 'TomTom', 'TomTom', None, 'Birthday'] })
需求:将原始DataFrame中holiday字段的列表值替换为单个holiday,替换规则为:
- 优先选择对应
result最大值的holiday; - 若
result相同,则选择出现次数(count)最多的; - 若次数也相同,可任选其一。
目前通过循环与多条件判断实现,希望得到更简洁的处理方法。
简洁解决方案
可以通过预计算每个holiday的优先级指标,结合apply快速完成替换,全程无需循环:
import pandas as pd # 1. 原始DataFrame df = pd.DataFrame({ 'index': [1, 2, 3, 4, 5, 6, 7], 'result': [80, 85, 90, 91, 92, 93, 94], 'holiday': ['Dam', 'Dam', 'Easter', ['Easter', 'TomTom'], ['TomTom', 'Christmas'], None, ['Birthday', 'Halloween']] }) # 2. 预计算每个holiday的全局最大result和出现次数 temp_explode = df.explode('holiday').dropna(subset=['holiday']) holiday_metrics = temp_explode.groupby('holiday').agg( max_result=('result', 'max'), count=('result', 'count') ).reset_index() # 3. 定义替换函数:对每个holiday项返回最优选择 def pick_best_holiday(holiday_item, result_val): if not isinstance(holiday_item, list): return holiday_item # 筛选当前列表中的候选holiday candidates = holiday_metrics[holiday_metrics['holiday'].isin(holiday_item)].copy() # 标记当前行result是否匹配该holiday的全局最大值 candidates['current_match'] = candidates['max_result'] == result_val # 按优先级排序:当前匹配度>全局max_result>出现次数 candidates = candidates.sort_values( by=['current_match', 'max_result', 'count'], ascending=[False, False, False] ) return candidates.iloc[0]['holiday'] # 4. 应用函数到每一行 df['holiday'] = df.apply(lambda row: pick_best_holiday(row['holiday'], row['result']), axis=1) print(df)
代码说明:
- 先通过
explode拆分所有holiday列表,统计每个holiday的全局指标,作为优先级判断的基础; - 替换函数针对列表类型的holiday,筛选候选后按规则排序,直接取最优项;
- 最终结果与期望输出完全一致,用Pandas原生操作替代循环,代码更简洁高效。
内容的提问来源于stack exchange,提问作者Lata
相关产品推荐
相关产品推荐

