如何使用pd.ExcelFile遍历Excel多工作表执行奖金计算代码?
解决Pandas遍历Excel多工作表计算奖金的问题
嘿,作为刚接触Pandas的新手,你遇到的问题其实是几个常见的小错误导致的,我来一步步帮你修正,让代码能遍历所有7个工作表,同时保留原数据并生成汇总表~
原代码里的几个关键问题
- 变量名混乱:你定义了
df = pd.ExcelFile(...),但循环里用了xlsx.sheet_names,变量名不匹配,导致循环根本没正确遍历工作表 - 硬编码工作表名:循环里一直只处理
'25.10'这个工作表,完全没用到循环变量sheet,所以其他6个表根本没被处理 - 数据存储错误:
dfs的定义格式不对,而且没有把每个处理后的工作表数据存起来,也没有收集所有表的数据做汇总 - 日期时间处理不完整:原数据里的
Date是日期,T1 Start/Finish是时间,应该合并成完整的datetime,不然只转时间的话,计算时长会有问题(比如跨天的情况) - Excel写入逻辑错误:用
mode='a'的话,如果新文件不存在会报错,而且没有把原处理后的工作表写入新文件
修正后的完整代码
import pandas as pd # 定义文件路径 input_file = 'filepath.xlsx' output_file = 'filepath/newfile.xlsx' # 读取Excel文件 excel_file = pd.ExcelFile(input_file) # 初始化字典存储每个处理后的工作表,以及总数据用于汇总 processed_sheets = {} all_data = pd.DataFrame() # 遍历所有工作表 for sheet_name in excel_file.sheet_names: # 读取当前工作表 df = excel_file.parse(sheet_name) # 合并日期和时间,生成完整的datetime列 df['T1 Start'] = pd.to_datetime(df['Date'] + ' ' + df['T1 Start']) df['T1 Finish'] = pd.to_datetime(df['Date'] + ' ' + df['T1 Finish']) # 计算工作时长(小时) df['Hours'] = (df['T1 Finish'] - df['T1 Start']).dt.total_seconds() / 3600 # 计算每小时平均派送包裹数 df['Average Parcels'] = df['T1 Delivered'] / df['Hours'] # 计算奖金:平均包裹数在[10,18)区间的话,乘以1.4,否则为0 df['Incentive'] = df['Average Parcels'].mul(1.4).where(df['Average Parcels'].between(10, 18, inclusive='left'), 0) # 把处理后的工作表存入字典 processed_sheets[sheet_name] = df # 将当前工作表数据追加到总数据中,用于后续汇总 all_data = pd.concat([all_data, df], ignore_index=True) # 生成汇总表(明确指定聚合字段,避免不必要的列被汇总) per_day = all_data.groupby(['Date', 'Rider']).agg( {'Hours': 'sum', 'T1 Delivered': 'sum', 'Incentive': 'sum'} ).reset_index() per_courier = all_data.groupby(['Rider']).agg( {'Hours': 'sum', 'T1 Delivered': 'sum', 'Incentive': 'sum'} ).reset_index() # 写入新Excel文件:先写所有处理后的原工作表,再写汇总表 with pd.ExcelWriter(output_file) as writer: # 写入每个处理后的原工作表 for sheet_name, df in processed_sheets.items(): df.to_excel(writer, sheet_name=sheet_name, index=False) # 写入汇总表 per_day.to_excel(writer, sheet_name='Per Day', index=False) per_courier.to_excel(writer, sheet_name='Per Courier', index=False) print("处理完成!新文件已包含所有原工作表(带计算结果)和两个汇总表")
代码改动说明
- 统一变量名:用
excel_file存储读取的Excel对象,避免变量混淆 - 遍历所有工作表:循环里用
excel_file.sheet_names拿到所有表名,逐个处理,不再硬编码 - 完整的日期时间处理:把
Date和T1 Start/Finish合并成完整的datetime,确保时长计算准确 - 存储处理后的数据:用
processed_sheets字典保存每个处理后的工作表,后续写入新文件时能保留原表结构和计算结果 - 汇总所有数据:用
all_data收集所有工作表的数据,这样Per Day和Per Courier是基于所有7天的数据汇总的 - 明确聚合字段:
groupby.agg()里指定要汇总的字段,避免默认汇总所有列导致的错误 - 正确写入Excel:直接创建新文件,先写入所有处理后的原工作表,再写入两个汇总表,确保所有内容都在新文件里
这样运行代码后,你就能得到预期的结果:新Excel文件里有7个原工作表(每个都包含计算出的Hours、Average Parcels、Incentive列),还有Per Day(按日期和骑手汇总)和Per Courier(按骑手汇总)两个工作表啦~
内容的提问来源于stack exchange,提问作者cchev
相关产品推荐
相关产品推荐

