Python求和函数异常排查:客户交易统计结果失真问题
问题排查与修正方案
核心错误点
- 日期转换逻辑错误:代码中
pd.to_datetime(df[start_date])完全错误,start_date是传入的日期字符串参数,不是DataFrame的列名,这里误将其当作列名读取数据,导致日期筛选条件彻底失效,统计范围完全偏离需求。 - 时间范围匹配错误:用
selected_df.shape[0](交易行数)截取历史数据的逻辑不成立。需求是统计相同时间长度的总额,而非相同交易行数。比如start_date到今天是30天,历史范围应该是start_date往前推30天到start_date,而非取最后N行——不同时间段交易密度不同,行数相同不代表时间范围一致。 - 客户维度缺失风险:若某客户在历史时间段无交易,
groupby后该客户会从before结果中消失,导致after和before的客户集合不匹配,无法准确对比同一客户的前后交易总额。
修正后的代码
import pandas as pd def sum_func(df: pd.DataFrame, start_date: str, date_col: str, sum_col: str): """ 统计起始日期至今日某列的总和,以及起始日期前相同时间范围的该列总和 参数: df: 原始DataFrame start_date: 统计起始日期(字符串格式,如'2023-01-01') date_col: 日期列的列名 sum_col: 需要求和的列名 返回: 包含"after"(起始日至今总和)和"before"(起始日前相同时长总和)的字典 """ # 转换日期格式并计算时间跨度 start_dt = pd.to_datetime(start_date) today_dt = pd.Timestamp.today() time_delta = today_dt - start_dt # 筛选起始日至今的数据 selected_df = df.loc[ (df[date_col] >= start_dt) & (df[date_col] <= today_dt) ].copy() # 筛选起始日前相同时间长度的数据 before_start_dt = start_dt - time_delta selected_df_before = df.loc[ (df[date_col] >= before_start_dt) & (df[date_col] < start_dt) ].copy() # 检查历史时间段数据是否存在 if selected_df_before.empty: raise ValueError("起始日期前没有足够的历史数据") # 分组求和并对齐客户维度 after_sum = selected_df.groupby('customer_no')[sum_col].sum() before_sum = selected_df_before.groupby('customer_no')[sum_col].sum() # 补全缺失客户,无交易则求和为0 before_sum = before_sum.reindex(after_sum.index, fill_value=0) return { "after": after_sum, "before": before_sum, }
关键修正说明
- 修复日期转换:将
pd.to_datetime(df[start_date])改为pd.to_datetime(start_date),正确使用传入的日期参数。 - 按时间跨度匹配历史范围:计算
start_date到今天的时间差time_delta,取start_dt - time_delta到start_dt的时间段,确保前后统计的是相同时长的交易数据。 - 对齐客户维度:用
reindex将before的结果索引对齐到after的客户列表,缺失客户填充0,保证两个结果的客户完全对应,便于对比分析。
内容的提问来源于stack exchange,提问作者Aon
相关产品推荐
相关产品推荐

