You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas:如何用两个DataFrame实现类Excel COUNTIF的带通配符统计?

问题

我正在编写脚本自动化Excel重复数据的转换/清洗工作,目前进展顺利,但遇到以下问题:
已导入相关DataFrame并完成过滤等清洗操作,创建了两个DataFrame——df2是基于df1生成的唯一ProductID列表,df1包含ProductID及对应的ProcCode。需要统计每个ProductID对应的ProcCode以P、A、X开头的次数(分别列为单独字段),但不清楚如何跨两个DataFrame实现。

示例数据:

import pandas as pd

df1 = pd.DataFrame({'ProductID': ["12441","44123","77880","12345","33445","77565","34354","77880","33445", "12345", "12441", "12441","12441","44123"], 
"ProcCode":["P34","P35","P67","P67","X77","P34","P35","P34","X77","P35","A55","P34","P35","A55"]})

df1内容:

ProductID ProcCode
0      12441      P34
1      44123      P35
2      77880      P67
3      12345      P67
4      33445      X77
5      77565      P34
6      34354      P35
7      77880      P34
8      33445      X77
9      12345      P35
10     12441      A55
11     12441      P34
12     12441      P35
13     44123      A55
df2 = pd.DataFrame({"ProductID": ["12441","44123","77880","12345","33445","77565"]})

df2内容:

ProductID
0     12441
1     44123
2     77880
3     12345
4     33445
5     77565

期望生成的df3:

df3 = pd.DataFrame({"ProductID":["12441","44123","77880","12345","33445","77565"], "CountofPCode":[3,1,2,3,0,1],"CountofXCode":[0,0,0,0,2,0]})

df3内容:

ProductID  CountofPCode  CountofXCode
0     12441             3             0
1     44123             1             0
2     77880             2             0
3     12345             3             0
4     33445             0             2
5     77565             1             0
解决方案

可以通过分组统计+左连接合并实现需求,下面提供两种写法:

写法一:分步实现(易理解)

  1. 给df1新增标记列,识别每个ProcCode的开头类型
# 标记是否以P/A/X开头,转为整数(True=1,False=0)
df1['is_P'] = df1['ProcCode'].str.startswith('P').astype(int)
df1['is_A'] = df1['ProcCode'].str.startswith('A').astype(int)
df1['is_X'] = df1['ProcCode'].str.startswith('X').astype(int)
  1. 按ProductID分组求和,得到每个ID的各开头次数
stats_df = df1.groupby('ProductID')[['is_P', 'is_A', 'is_X']].sum().reset_index()
  1. 与df2左连接,确保保留df2中所有唯一ID,缺失统计项填充0并调整列名
df3 = df2.merge(stats_df, on='ProductID', how='left').fillna(0)
# 重命名列名匹配需求
df3 = df3.rename(columns={
    'is_P': 'CountofPCode',
    'is_A': 'CountofACode',
    'is_X': 'CountofXCode'
})
# 转换为整数类型
df3[['CountofPCode', 'CountofACode', 'CountofXCode']] = df3[['CountofPCode', 'CountofACode', 'CountofXCode']].astype(int)

写法二:链式写法(更简洁高效)

无需新增临时列,直接在聚合阶段完成统计:

df3 = df2.merge(
    df1.groupby('ProductID').agg(
        CountofPCode=('ProcCode', lambda x: x.str.startswith('P').sum()),
        CountofACode=('ProcCode', lambda x: x.str.startswith('A').sum()),
        CountofXCode=('ProcCode', lambda x: x.str.startswith('X').sum())
    ).reset_index(),
    on='ProductID',
    how='left'
).fillna(0).astype({
    'CountofPCode': int,
    'CountofACode': int,
    'CountofXCode': int
})

两种写法最终得到的df3均与期望结果一致,若不需要A开头的统计,只需删除对应列的代码即可。

内容的提问来源于stack exchange,提问作者conrito345

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 23:02:35