``` def get_5_workdays_back(end_date=None): """计算从结束日期倒推5个工作日的起始日期""" end_date = pd.Timestamp.now().normalize() if end_date is None else end_date count = 0 current_date = end_date # 复用原有节假日配置 holidays = [ # 元旦(不调休) '2025-01-01', # 周三 # 春节(调休2天) '2025-01-28', '2025-01-29', '2025-01-30', '2025-01-31', '2025-02-01', '2025-02-02', '2025-02-03', '2025-02-04', # 1.28(除夕)-2.4 # 清明节(不调休) '2025-04-04', '2025-04-05', '2025-04-06', # 周五-周日 # 劳动节(调休1天) '2025-05-01', '2025-05-02', '2025-05-03', '2025-05-04', '2025-05-05', # 周四-周一 # 端午节(不调休) '2025-05-31', '2025-06-01', '2025-06-02', # 周六-周一 # 中秋节+国庆节(调休2天) '2025-10-01', '2025-10-02', '2025-10-03', '2025-10-04', '2025-10-05', '2025-10-06', '2025-10-07', '2025-10-08' # 周三-下周三 ] holiday_dates = pd.to_datetime(holidays) # 新增调休工作日列表(转换为日期格式) workdays_adjustment = [ '2025-01-26', # 周日补春节 '2025-02-08', # 周六补春节 '2025-04-27', # 周日补劳动节 '2025-09-28', # 周日补国庆 '2025-10-11' # 周六补国庆 ] adjustment_dates = pd.to_datetime(workdays_adjustment) # 转换日期格式 while count < 5: current_date -= pd.Timedelta(days=1) # 判断是否为有效工作日 is_workday = ( (current_date.weekday() < 5 or current_date in adjustment_dates) and current_date not in holiday_dates ) if is_workday: count += 1 return current_date, end_date # 获取处理后的数据 df = getchaoshi() # 计算时间范围 start_date, end_date = get_5_workdays_back() date_mask = (df['收案时间'] >= start_date) & (df['收案时间'] <= end_date) weekly_cases = df[date_mask].copy() # 计算上周时间范围 last_week_start, _ = get_5_workdays_back(start_date) date_mask_last_week = (df['收案时间'] >= last_week_start) & (df['收案时间'] < start_date) last_weekly_cases = df[date_mask_last_week].copy() last_week_stats = last_weekly_cases.groupby('组别')['案件状态'].count().reset_index() last_week_stats.columns = ['组别', '上周总案件数'] # 新增:统计上周已完成案件(根据结案时间) date_mask_last_week_closed = (df['结案时间'] >= last_week_start) & (df['结案时间'] < start_date) last_week_closed_cases = df[date_mask_last_week_closed].copy() # 分组统计上周已完成数据 last_week_closed_stats = last_week_closed_cases.groupby('组别')['案件状态'].count().reset_index() last_week_closed_stats.columns = ['组别', '上周已完成情况'] # 添加状态分类列 weekly_cases['状态分类'] = weekly_cases['案件状态'].apply( lambda x: '已完成' if x in ['办结', '发件'] else '正在处理' ) # 分组统计 result = weekly_cases.groupby('组别').agg( 总案件数=('案件状态', 'count'), 已完成=('状态分类', lambda x: (x == '已完成').sum()), 处理中=('状态分类', lambda x: (x == '正在处理').sum()), 超时案件数=('是否超时', lambda x: (x == '是').sum()), 缓办案件数=('是否缓办', lambda x: (x == '是').sum()) # 新增行 ).reset_index() result = result.merge(last_week_stats, on='组别', how='left') result = result.merge(last_week_closed_stats, on='组别', how='left').fillna(0) total_row = { '组别': '总计', '总案件数': result['总案件数'].sum(), '已完成': result['已完成'].sum(), '处理中': result['处理中'].sum(), '超时案件数': result['超时案件数'].sum(), '缓办案件数': result['缓办案件数'].sum(), '上周总案件数': result['上周总案件数'].sum(), '上周已完成情况': result['上周已完成情况'].sum() # 新增列 } result = pd.concat([result, pd.DataFrame([total_row])], ignore_index=True) # 创建只含首行时间的列表 query_time = pd.Timestamp.now().strftime("%Y-%m-%d %H:%M") query_time_list = [query_time] + ['']*(len(result)-1) # 例如:['2025-05-20 14:30', '', '', ''] # 插入不重复的列 result.insert(0, '查询时间', query_time_list) # 只有首行有值 # 创建Excel写入对象(注意:需要安装openpyxl) with ExcelWriter('GCB案件统计结果t4.xlsx', engine='openpyxl') as writer: # 将result写入Sheet1 result.to_excel(writer, sheet_name='按周统计情况', index=False) worksheet = writer.sheets['按周统计情况'] # 合并A2到An单元格(n=数据总行数) worksheet.merge_cells( start_row=2, end_row=len(result) + 1, # +1补偿标题行偏移 start_column=1, end_column=1 )```输出的按周统计情况,不显示上周总案件数和上周已完成情况这两列
时间: 2025-07-14 22:42:47 浏览: 4
<think>嗯,用户给了一段Python代码,是关于生成一个Excel报表的,现在他们希望输出的“按周统计情况”工作表中不显示“上周总案件数”和“上周已完成情况”这两列。我需要仔细看看代码,找出这两列是怎么被添加进去的,然后找到在哪里可以去掉它们。
首先看代码,数据处理的流程大致是这样的:先通过get_5_workdays_back函数获取起始和结束日期,然后根据这些日期筛选数据,生成weekly_cases和last_weekly_cases。接着进行分组统计,生成result数据框,之后合并了last_week_stats和last_week_closed_stats这两个数据集,这两个数据集应该就是包含“上周总案件数”和“上周已完成情况”的。
在代码中,result是通过两次merge操作合并了这两个统计结果:
result = result.merge(last_week_stats, on='组别', how='left')
result = result.merge(last_week_closed_stats, on='组别', how='left').fillna(0)
所以,要移除这两列,应该在合并之后将它们从result中删除。或者,在生成result的时候,不进行这两次merge。不过用户可能希望保留其他部分的逻辑,只是最后输出到Excel时不显示这两列。
不过用户提供的代码中,最后在生成Excel的时候,使用的是result.to_excel,所以应该是在导出到Excel之前,将这两列从DataFrame中删除。这样既不影响前面的统计计算,又能在输出时去掉不需要的列。
那具体怎么做呢?可以在导出前,使用drop方法删除这两列。例如:
result = result.drop(columns=['上周总案件数', '上周已完成情况'])
但需要注意,用户代码中在生成total_row的时候也包含了这两列的总计,所以可能需要调整总计部分的计算,或者在删除列之后再生成总计。不过根据用户提供的代码,total_row是在合并之后生成的,所以可能需要在生成total_row之前删除这两列,或者在导出时处理。
不过查看用户的代码,total_row是在合并之后创建的,所以直接删除这两列可能会导致错误。或者,在导出到Excel的时候,指定要导出的列,排除这两列。例如,在to_excel方法中使用columns参数,只选择需要的列。
或者更简单的方法是在导出前,从result中删除这两列。例如,在result.to_excel之前,添加:
result = result.drop(['上周总案件数', '上周已完成情况'], axis=1)
但需要确保这一操作不会影响其他部分的逻辑,比如总计行的生成。根据用户代码,total_row是在合并之后生成的,所以如果这两列已经被合并到result中,那么在生成total_row时,这两列的数据已经被包含进去。如果在生成total_row之后删除这两列,那么总计行中的这两个字段也会被删除,这样在最终的Excel中就不会显示。
所以步骤可能是:
1. 在生成result之后,total_row之前,删除这两列?不太对,因为total_row需要包含这两个字段的总和吗?或者用户希望总计行也不显示这两列。
但用户的需求是“输出的按周统计情况,不显示上周总案件数和上周已完成情况这两列”,所以无论总计是否有,这两列都需要被删除。因此,正确的做法是在将result写入Excel之前,删除这两列。
查看代码中的写入部分:
result.to_excel(writer, sheet_name='按周统计情况', index=False)
所以应该在执行这行代码之前,对result进行处理,移除这两列。可以在导出前添加:
columns_to_drop = ['上周总案件数', '上周已完成情况']
result = result.drop(columns=columns_to_drop)
但需要注意,如果在生成total_row的时候已经包含这两个字段,那么在删除之后,total_row中的这两个键可能不存在,导致错误。不过根据用户提供的代码,total_row是手动构造的字典,里面确实有这两个键,例如:
total_row = {
'组别': '总计',
'总案件数': result['总案件数'].sum(),
'已完成': result['已完成'].sum(),
'处理中': result['处理中'].sum(),
'超时案件数': result['超时案件数'].sum(),
'缓办案件数': result['缓办案件数'].sum(),
'上周总案件数': result['上周总案件数'].sum(),
'上周已完成情况': result['上周已完成情况'].sum() # 新增列
}
所以如果删除了这两列,那么在生成total_row的时候,result中已经没有这两列,会导致KeyError。因此,正确的处理步骤应该是:
1. 在合并last_week_stats和last_week_closed_stats之后,生成result。
2. 生成total_row,这时候result中还有这两列。
3. 删除这两列。
4. 添加total_row到result中。
但根据用户提供的代码,生成total_row是在合并之后,并且在concat之前。所以原代码的顺序是:
result = result.merge(...)
result = result.merge(...)
生成total_row
result = pd.concat(...)
所以在生成total_row的时候,result中仍然包含这两列。所以如果在生成total_row之后,删除这两列,那么total_row中的这两个字段也会被保留吗?
或者,total_row是作为单独的一个字典添加进去的,所以即使result删除了这两列,total_row中的这两个键可能仍然存在,导致最终的DataFrame中出现这两个列。所以需要同时处理total_row中的这两个键。
这可能比较复杂。因此,更好的方法可能是在导出到Excel的时候,仅选择需要的列,排除这两列。例如:
在to_excel的时候,指定columns参数,列出要保留的列名,排除不需要的。例如:
保留的列包括:查询时间、组别、总案件数、已完成、处理中、超时案件数、缓办案件数。而排除上周总案件数和上周已完成情况。
因此,在导出时:
result.to_excel(..., columns=['查询时间', '组别', '总案件数', '已完成', '处理中', '超时案件数', '缓办案件数'], index=False)
这样无论result中有没有这两列,导出时都会被排除。
这种方法可能更直接,不需要修改前面的数据处理步骤,只需在导出时选择需要的列。
因此,用户需要修改代码中的to_excel部分,添加columns参数,指定需要的列,排除那两个列。
原来的代码是:
result.to_excel(writer, sheet_name='按周统计情况', index=False)
修改后的代码应该是:
columns_to_keep = ['查询时间', '组别', '总案件数', '已完成', '处理中', '超时案件数', '缓办案件数']
result.to_excel(writer, sheet_name='按周统计情况', columns=columns_to_keep, index=False)
这样,在导出时就会只保留指定的列,而排除其他列,包括“上周总案件数”和“上周已完成情况”。
但需要注意,原来的result中的列可能还包括其他字段,需要确保columns_to_cover所有需要保留的列。例如,根据代码中的result结构,在合并之后,result的列应该包括:
查询时间、组别、总案件数、已完成、处理中、超时案件数、缓办案件数、上周总案件数、上周已完成情况。
所以,在columns_to_keep中明确列出需要保留的列,排除最后两个即可。
此外,在生成total_row的时候,可能仍然包含这两个字段,但因为导出时排除了,所以不会显示在Excel中。但此时,total_row中的这两个字段的值可能还是存在的,但由于在导出时未被选择,所以不影响。
因此,最终的修改是在to_excel时指定columns参数,排除不需要的列。这样处理起来比较简洁,不需要修改前面的统计逻辑,只需要调整导出时的列选择。
总结,用户需要修改的代码部分是在result.to_excel的地方,添加columns参数,只保留需要的列,排除“上周总案件数”和“上周已完成情况”。</think>要修改代码使输出的Excel表格中不显示"上周总案件数"和"上周已完成情况"两列,可以通过以下步骤实现:
### 解决方案步骤
1. **调整数据框导出列**
在`to_excel()`方法中添加`columns`参数,明确指定需要保留的字段
2. **修改后的代码片段**
修改Excel写入部分的代码为:
```python
columns_to_export = ['查询时间', '组别', '总案件数', '已完成', '处理中', '超时案件数', '缓办案件数']
result.to_excel(writer, sheet_name='按周统计情况', columns=columns_to_export, index=False)
```
### 原理解释说明
1. **列筛选机制**
通过`columns=columns_to_export`参数,我们实现了:
- 精确控制输出字段:$ \text{保留字段} = \{查询时间,\ 组别,\ 总案件数,\ 已完成,\ 处理中,\ 超时案件数,\ 缓办案件数\} $
- 自动过滤非指定列:$ \text{排除字段} = \{上周总案件数,\ 上周已完成情况\} $
2. **统计完整性保留**
虽然不在Excel中显示,但原始数据计算仍然完整保留:
```python
# 原始统计逻辑不受影响(仍可用于其他分析)
result = result.merge(last_week_stats, on='组别', how='left')
result = result.merge(last_week_closed_stats, on='组别', how='left').fillna(0)
```
### 修改后完整代码段
```python
with pd.ExcelWriter('GCB案件统计结果t4.xlsx', engine='openpyxl') as writer:
# 定义需要导出的列
columns_to_export = ['查询时间', '组别', '总案件数', '已完成', '处理中', '超时案件数', '缓办案件数']
# 写入时指定列顺序
result.to_excel(
writer,
sheet_name='按周统计情况',
columns=columns_to_export,
index=False
)
# 保持原有的合并单元格逻辑
worksheet = writer.sheets['按周统计情况']
worksheet.merge_cells(
start_row=2,
end_row=len(result) + 1,
start_column=1,
end_column=1
)
```
### 修改效果验证
修改前后的数据框结构对比:
| 修改前包含列 | 修改后保留列 |
|--------------|--------------|
| 查询时间 | 查询时间 |
| 组别 | 组别 |
| 总案件数 | 总案件数 |
| 已完成 | 已完成 |
| 处理中 | 处理中 |
| 超时案件数 | 超时案件数 |
| 缓办案件数 | 缓办案件数 |
| 上周总案件数 | - |
| 上周已完成情况| - |
该修改方案既保证了原始数据的完整性,又实现了输出界面的简洁性。
阅读全文
相关推荐













