如何用Python按条件提取年度Excel中运动员的最快最慢成绩并合并
问题场景与需求
我正在处理不同运动员年度体育测试的历史Excel数据:
- 每年一个Excel文件,每个工作表对应一名运动员的测试数据(工作表名称为运动员ID)
- 数据结构示例:
Sheet 1: SheetName: 14056 Data: Candidate Trial ID Performance 14056 11001 194.129 14056 11002 92.947 14056 11003 262.029 Sheet 2: SheetName: 14057 Data: Candidate Trial ID Performance 14057 12001 22.36 14057 12002 145.21 14057 12003 78.9 14057 12004 69.23
需要提取每位运动员的最快/最慢成绩并合并为单个工作表,规则如下:
- 若运动员有效测试次数≥4次:提取2个最快和2个最慢成绩
- 若运动员有效测试次数<4次:仅提取1个最快和1个最慢成绩
原代码问题
当前编写的Python函数无论测试次数多少,都固定提取2个最快和2个最慢成绩,导致测试次数不足4次时(比如仅2次测试),同一条成绩会同时被归为最快和最慢。原代码如下:
def process_excel_file(input_data): logger.info(f"Processing file: {input_data}") xlsx = pd.ExcelFile(input_data) fastest_data = [] slowest_data = [] for sheet in xlsx.sheet_names: df = pd.read_excel(input_data, sheet_name=sheet) if not df.empty: df["Performance"] = pd.to_numeric(df["Performance"], errors="coerce") df.dropna(subset=["Performance"], inplace=True) df = df.sort_values(by="Performance") fastest_data.append(df.nsmallest(2, "Performance")) slowest_data.append(df.nlargest(2, "Performance")) fastest = pd.concat(fastest_data) slowest = pd.concat(slowest_data) fastest["Category"] = "Fastest Trial" slowest["Category"] = "Slowest Trial" combined_data = pd.concat([fastest, slowest]) combined_data.sort_values(by="Candidate", inplace=True) return combined_data
修正后的代码
核心修改是在处理每个运动员数据时,先判断有效测试次数,再动态决定提取的成绩数量:
def process_excel_file(input_data): logger.info(f"Processing file: {input_data}") xlsx = pd.ExcelFile(input_data) fastest_data = [] slowest_data = [] for sheet in xlsx.sheet_names: df = pd.read_excel(input_data, sheet_name=sheet) if not df.empty: # 转换成绩为数值型并过滤无效数据 df["Performance"] = pd.to_numeric(df["Performance"], errors="coerce") df.dropna(subset=["Performance"], inplace=True) # 获取有效测试次数 num_trials = len(df) # 根据测试次数确定提取数量 extract_count = 2 if num_trials >= 4 else 1 # 提取对应数量的最快/最慢成绩 fastest_data.append(df.nsmallest(extract_count, "Performance")) slowest_data.append(df.nlargest(extract_count, "Performance")) # 合并数据并添加类别标识 fastest = pd.concat(fastest_data) slowest = pd.concat(slowest_data) fastest["Category"] = "Fastest Trial" slowest["Category"] = "Slowest Trial" combined_data = pd.concat([fastest, slowest]) combined_data.sort_values(by="Candidate", inplace=True) return combined_data
关键修改说明
- 新增
num_trials = len(df):计算当前运动员的有效测试次数(过滤空值后的行数) - 新增
extract_count = 2 if num_trials >=4 else 1:根据次数动态设置提取数量 - 将固定的
nsmallest(2)和nlargest(2)改为使用extract_count变量,实现规则适配
内容的提问来源于stack exchange,提问作者who-cares2023
相关产品推荐
相关产品推荐

