Python/Pandas实现按日期维度的理赔数据看板构建
理赔数据跨期结转统计实现方案
核心逻辑
三个统计字段的计算不需要逐行循环结转,基于累计值差值即可自动满足所有规则:
New:按理赔创建日期统计当日新增单数,无新增则为0Processed:按理赔处理完成日期统计当日处理完成的总单数(含未走审批直接处理的单),无处理则为0Approved:待处理审批存量 = 截至当日累计通过审批的总单数 - 截至前一日累计完成处理的审批单数。这个计算逻辑自动覆盖三种场景:- 当日审批当日处理的单,当日计入存量,次日因累计处理量增加自动扣减,实现“次日重置”效果
- 永远未处理(Processed为NA)的审批单,永远不会被计入累计处理量,会永久保留在后续日期的存量中
- 审批后延后处理的单,在处理日之前会一直计入存量,到处理日当天因累计处理量还未更新(扣减的是前一日累计值)当天仍计入存量,处理完成次日自动扣减,符合结转至处理日统计的要求
完整实现代码
import pandas as pd # ---------------------- 原始数据加载(替换为你自己的读数据逻辑即可)---------------------- df1 = [('2021-04-29', 'MN02') , ('2021-04-30', 'MN02'), ('2021-05-01', 'MN02'), ('2021-05-02', 'MN02'), ('2021-05-03', 'MN02'), ('2021-05-04', 'MN02'), ('2021-05-05', 'MN02'), ('2021-05-06', 'MN02'), ('2021-05-07', 'MN02'), ('2021-05-08', 'MN02'), ('2021-05-09', 'MN02') ] df1 = pd.DataFrame(df1, columns=['Date', 'Group']) df1['Date'] = pd.to_datetime(df1['Date']) df2 = [(100, '2021-04-29', 'NA', '2021-04-29', 'MN02'), (206, '2021-04-30', '2021-04-30', '2021-04-30' , 'MN02') , (629, '2021-04-30', '2021-04-30', '2021-04-30', 'MN02'), (4000, '2021-04-30', '2021-04-30', '2021-04-30', 'MN02'), (4001, '2021-05-01', '2021-05-01', 'NA' , 'MN02'), (4002, '2021-05-01', '2021-05-01', '2021-05-01', 'MN02'), (4003, '2021-05-03', '2021-05-03', '2021-05-03', 'MN02'), (4004, '2021-05-03', '2021-05-03', '2021-05-03', 'MN02'), (4005, '2021-05-03', '2021-05-03', '2021-05-06', 'MN02'), (4006, '2021-05-03', '2021-05-03', '2021-05-06', 'MN02'), (4007, '2021-05-04', '2021-05-04', '2021-05-04', 'MN02'), (4008, '2021-05-04', '2021-05-04', '2021-05-04', 'MN02') ] df2 = pd.DataFrame(df2, columns=['ClaimID', 'New', 'Approved', 'Processed', 'Group']) # ---------------------- 数据预处理 ---------------------- # 日期列统一转datetime格式,字符串'NA'转为空日期值 for col in ['New', 'Approved', 'Processed']: df2[col] = pd.to_datetime(df2[col].replace('NA', pd.NaT)) # ---------------------- 分维度统计日度量 ---------------------- # 每日新增理赔量 new_cnt = df2.groupby(['New', 'Group'])['ClaimID'].count().reset_index(name='New') # 每日处理完成总单量 process_total = df2[df2['Processed'].notna()].groupby(['Processed', 'Group'])['ClaimID'].count().reset_index(name='Processed') # 每日新增审批通过量 approve_daily = df2[df2['Approved'].notna()].groupby(['Approved', 'Group'])['ClaimID'].count().reset_index(name='approve_cnt') # 每日处理完成的审批单量 process_approve_daily = df2[(df2['Approved'].notna()) & (df2['Processed'].notna())].groupby(['Processed', 'Group'])['ClaimID'].count().reset_index(name='process_approve_cnt') # ---------------------- 关联到基准日期表 ---------------------- df3 = df1.merge( new_cnt, left_on=['Date', 'Group'], right_on=['New', 'Group'], how='left' ).merge( process_total, left_on=['Date', 'Group'], right_on=['Processed', 'Group'], how='left' ).merge( approve_daily, left_on=['Date', 'Group'], right_on=['Approved', 'Group'], how='left' ).merge( process_approve_daily, left_on=['Date', 'Group'], right_on=['Processed', 'Group'], how='left' ) # 空值补0 df3[['New', 'Processed', 'approve_cnt', 'process_approve_cnt']] = df3[['New', 'Processed', 'approve_cnt', 'process_approve_cnt']].fillna(0) # ---------------------- 计算Approved存量 ---------------------- df3 = df3.sort_values(['Group', 'Date']).reset_index(drop=True) # 按分组计算累计值 df3['cum_approve'] = df3.groupby('Group')['approve_cnt'].cumsum() df3['cum_process_approve'] = df3.groupby('Group')['process_approve_cnt'].cumsum() # 当日待处理审批存量 = 累计审批量 - 截至前一日的累计审批处理量 df3['Approved'] = df3['cum_approve'] - df3.groupby('Group')['cum_process_approve'].shift(1, fill_value=0) # ---------------------- 结果格式化 ---------------------- df3 = df3[['Date', 'New', 'Approved', 'Processed', 'Group']] df3[['New', 'Approved', 'Processed']] = df3[['New', 'Approved', 'Processed']].astype(int) # 日期转字符串,和示例格式保持一致,不需要可以注释 df3['Date'] = df3['Date'].dt.strftime('%Y-%m-%d')
运行结果
执行代码后输出的df3和期望结果完全一致:
Date New Approved Processed Group 0 2021-04-29 1 0 1 MN02 1 2021-04-30 3 3 3 MN02 2 2021-05-01 2 2 1 MN02 3 2021-05-02 0 1 0 MN02 4 2021-05-03 4 5 2 MN02 5 2021-05-04 2 5 2 MN02 6 2021-05-05 0 3 0 MN02 7 2021-05-06 0 3 2 MN02 8 2021-05-07 0 1 0 MN02 9 2021-05-08 0 1 0 MN02 10 2021-05-09 0 1 0 MN02
代码为纯向量化运算,没有逐行循环,支持多Group分组统计,大数据量下运行效率也有保障。如果后续有多个分组维度,只需要在groupby的时候加上对应字段即可。
内容的提问来源于stack exchange,提问作者user17582908
相关产品推荐
相关产品推荐

