Python pandas实现Excel COUNTIFS多条件计数方法
原代码错误点
- 逻辑完全偏离COUNTIFS规则:将单值与整列直接比较、错误对三个独立条件的布尔值直接求和,没有统计同时满足三个条件的总行数
- 存在未定义变量:代码中混用了未声明的
big_df1,且错误调用datetime()处理布尔判断结果,本身就无法正常运行 - 逐行
apply的实现思路效率极低,pandas向量化运算性能远高于逐行遍历写法
可直接复现Excel结果的实现代码
import pandas as pd # ----- 测试数据集构造代码 ----- df = pd.DataFrame({'ID' :[302896,302896,302896,302896,302896,302896,302896,302896,541646,541646,541646,541646,541646,541646,541646,541646,614663,658798,658798,658798,658798,658798,658798,658798,658798] , 'Date' : [44659.7044791667,44659.7044791667,44659.7044791667,44659.7044791667,44659.7044791667,44659.7044791667,44659.7044791667,44659.7044791667,44663.973587963,44663.973587963,44663.973587963,44663.973587963,44663.973587963,44663.973587963,44663.973587963,44663.973587963,44744.3235185185,44687.8571643519,44687.8571643519,44702.4230324074,44702.4230324074,44702.4230324074,44702.4230324074,44702.4230324074,44702.4230324074], 'Risk' : ['Above Normal','Above Normal','Above Normal','Above Normal','Above Normal','Above Normal','Above Normal','Above Normal','Above Normal','Above Normal','Above Normal','Above Normal','Above Normal','Above Normal','Above Normal','Above Normal','Normal','High','High','High','High','High','High','High','High', ]}) # 若需要保留原始行顺序,先存储原索引 df['original_order'] = df.index # 按ID、日期升序排序,保证累计计数时只统计到日期<=当前行的记录 df = df.sort_values(by=['ID', 'Date']).reset_index(drop=True) # 批量生成三个风险等级的计数列,完全对齐Excel COUNTIFS逻辑 for risk_type in ['High', 'Above Normal', 'Normal']: # 先标记行是否匹配目标风险等级,再按ID分组做累计求和 df[risk_type] = (df['Risk'] == risk_type).groupby(df['ID']).cumsum().astype(int) # 恢复原始行顺序,删除临时索引列 df = df.sort_values(by='original_order').drop(columns='original_order').reset_index(drop=True)
逻辑对应说明
代码逻辑和Excel三个COUNTIFS公式一一对应:
- 以ID为分组键做统计,匹配
ID等于当前行ID的条件 - 提前按日期升序排序后,累计求和
cumsum()只会统计当前行及之前的记录,天然匹配日期小于等于当前行日期的条件 - 仅对风险等级匹配的行记1再求和,匹配
风险等级等于目标值的条件
运行结果验证:ID为302896、541646的分组全为Above Normal风险,对应列会从1累计到8,其余两列值为0;ID为614663的单条记录为Normal风险,Normal列值为1,其余两列为0;ID为658798的分组共8条High风险记录,前2条日期较早的记录High列值为1、2,后6条记录High列从3累计到8,其余两列为0,和Excel公式计算结果完全一致。
内容的提问来源于stack exchange,提问作者JK1185
相关产品推荐
相关产品推荐

