Pandas实现列范围取最大值,用第二列范围进行平局决胜
解决DataFrame多轮筛选最爱水果的问题
问题背景
现有包含受访者水果评分与识别分的DataFrame,需按以下规则确定每位受访者的最爱水果:
- 优先选择评分最高的水果(对应
*_rati列) - 若多个水果评分相同,选择其中识别分最高的(对应
*_reco列) - 若识别分仍有平局,从候选水果中随机选取一个
原始数据代码:
import pandas as pd df_raw = pd.DataFrame(data=[ ["name1", 10, 10, 9, 10, 10, 10], ["name2", 10, 10, 8, 10, 8, 4], ["name3", 10, 8, 8, 10, 8, 8], ["name4", 5, 10, 10, 5, 10, 8]], columns=["name", "banana_rati", "mango_rati", "orange_rati", "banana_reco", "mango_reco", "orange_reco"])
实现方案
以下是完整的代码实现,包含多轮筛选与随机平局处理:
import pandas as pd import numpy as np # 定义评分、识别分列组,提取水果名称 rati_cols = ["banana_rati", "mango_rati", "orange_rati"] reco_cols = ["banana_reco", "mango_reco", "orange_reco"] fruits = [col.replace("_rati", "") for col in rati_cols] # 生成每行评分最高的候选水果掩码 rati_max = df_raw[rati_cols].max(axis=1) rati_candidates = df_raw[rati_cols].eq(rati_max, axis=0) # 定义平局处理函数 def resolve_tie(row): mask = rati_candidates.loc[row.name] # 情况1:只有一个评分最高的水果 if mask.sum() == 1: return fruits[mask.idxmax()] # 情况2:多个评分最高,用识别分筛选 else: # 提取候选水果的识别分 reco_vals = row[reco_cols][mask.values] reco_max = reco_vals.max() final_reco_candidates = reco_vals[reco_vals == reco_max].index final_fruits = [col.replace("_reco", "") for col in final_reco_candidates] # 情况2.1:识别分筛选后只剩一个 if len(final_fruits) == 1: return final_fruits[0] # 情况2.2:识别分仍平局,随机选 else: return np.random.choice(final_fruits) # 应用函数生成结果列 df_raw['fav_fruit'] = df_raw.apply(resolve_tie, axis=1) # 输出结果 print(df_raw['fav_fruit'])
代码说明
- 列组定义:提前划分评分、识别分列组,提取水果名称简化结果返回
- 第一轮筛选:通过布尔掩码标记每行评分最高的水果
- 平局处理:
- 若只有一个候选,直接返回对应水果
- 若有多个候选,提取其识别分并筛选最高分
- 识别分仍平局时,用
np.random.choice随机选取一个
- 结果生成:用
apply逐行处理,生成最终的fav_fruit列
运行后结果符合预期:name1会随机返回banana或mango,name2返回banana,name3返回banana,name4返回mango。
内容的提问来源于stack exchange,提问作者Ivo
相关产品推荐
相关产品推荐

