基于Python/Pandas将原始SLT数据转换为月度统计报表表格的技术问询
嘿,我太懂你这种在Pandas里复刻Excel数据透视表的纠结了——明明Excel里拖拖拽拽就能搞定,到了代码里就总踩坑。别慌,我一步步帮你实现你要的报表,顺便帮你排查下之前可能出错的点~
先理清楚核心需求
你需要:
- 按「年-月」维度分组作为行
- 统计每个月内
Made和Missed的记录数作为列 - 计算对应月份
SLT Percent的平均值(转成百分比格式)
第一步:先处理数据基础问题
首先你的原始数据里有个小坑:SLT State里有个拼写错误的Mised,得先修正,不然分组会多出一列,结果肯定不对。另外,SLT Date是字符串格式,必须转成Pandas能识别的日期类型,否则按年月分组会乱套。
完整实现代码
我先模拟你的原始数据,然后一步步写代码:
import pandas as pd # 模拟你的原始数据 data = { 'ID': [1,2,11,12,13,14,18,19,20,21,22,23,24,25,26,27,28,29,30], 'SLT Date': ['5/28/2018', '11/13/2018', '3/6/2019', '5/20/2019', '10/25/2021', '11/12/2019', '6/4/2020', '6/11/2020', '8/6/2020', '12/9/2021', '5/16/2022', '3/22/2018', '3/20/2018', '5/11/2018', '12/20/2018', '5/12/2022', '10/7/2021', '3/21/2019', '4/24/2019'], 'SLT Percent': [1,0,0,1,1,1,1,1,1,0,1,0,0,1,0,1,1,1,0], 'SLT State': ['Made', 'Mised', 'Missed', 'Made', 'Made', 'Made', 'Made', 'Made', 'Made', 'Missed', 'Made', 'Missed', 'Missed', 'Made', 'Missed', 'Made', 'Made', 'Made', 'Missed'] } df = pd.DataFrame(data) # 1. 修正SLT State的拼写错误 df['SLT State'] = df['SLT State'].replace('Mised', 'Missed') # 2. 把SLT Date转成日期格式,并提取年月作为分组键 df['SLT Date'] = pd.to_datetime(df['SLT Date']) df['Year-Month'] = df['SLT Date'].dt.to_period('M') # 得到类似"2018-05"的格式 # 3. 用groupby.agg一次性完成所有聚合(最简洁的方式) final_report = df.groupby('Year-Month').agg( Made=('SLT State', lambda x: (x == 'Made').sum()), # 统计Made的数量 Missed=('SLT State', lambda x: (x == 'Missed').sum()), # 统计Missed的数量 Percent=('SLT Percent', lambda x: f"{x.mean() * 100:.0f}%") # 计算均值并转成百分比 ).reset_index().rename(columns={'Year-Month': 'Date'}) print(final_report)
运行结果(和你的需求匹配)
Date Made Missed Percent 0 2018-03 0 2 0% 1 2018-05 2 0 100% 2 2018-11 0 1 0% 3 2018-12 0 1 0% 4 2019-03 1 1 50% 5 2019-04 0 1 0% 6 2019-05 1 0 100% 7 2019-11 1 0 100% 8 2020-06 2 0 100% 9 2020-08 1 0 100% 10 2021-10 2 0 100% 11 2021-12 0 1 0% 12 2022-05 2 0 100%
为什么你之前可能出错?
- 日期格式没处理:如果
SLT Date还是字符串,按年月分组会按字符串排序(比如"11/13/2018"会和"11/12/2019"被错误归为一组),而不是时间维度的分组。 - 拼写错误没修正:原始数据里的
Mised会导致分组后多出一列,结果不符合预期。 - 聚合方式没搭配对:如果分开用
groupby+unstack,没有处理缺失值(比如某个月份只有Made没有Missed),会出现NaN,需要用fill_value=0补全。
备选方案:用pivot_table贴近Excel逻辑
如果你更习惯Excel数据透视表的思维,也可以用pivot_table实现:
# 生成计数透视表 count_table = pd.pivot_table( df, index='Year-Month', columns='SLT State', values='ID', aggfunc='count', fill_value=0 ).reset_index() # 生成百分比均值表 percent_table = df.groupby('Year-Month')['SLT Percent'].mean().reset_index() percent_table['Percent'] = percent_table['SLT Percent'].apply(lambda x: f"{x*100:.0f}%") # 合并两个表 final_report = pd.merge(count_table, percent_table[['Year-Month', 'Percent']], on='Year-Month') final_report = final_report.rename(columns={'Year-Month': 'Date'})
内容的提问来源于stack exchange,提问作者Gorhell




