统计api_spec_id对应type的四类值时结果异常,求修正方案
Pandas分组统计API规格ID的四类情况修正方案
原始数据
import pandas as pd data = { 'api_spec_id': [213, 213, 213, 345, 345, 345, 678, 678, 678, 123, 123], 'type': ['BR', 'BR', 'NBR', 'NBR', 'NBR', 'NBR', 'BR', 'BR', 'BR', 'BR', 'BR'] } df = pd.DataFrame(data)
需求说明
需要统计以下四类api_spec_id的数量:
- 所有行
type均为BR的ID数量 - 至少有一行
type为BR的ID数量 - 至少有一行
type为NBR的ID数量 - 所有行
type均为NBR的ID数量
问题分析
你当前代码中最后两个统计结果异常相同,本质是重复遍历数据时的逻辑复用性差,容易出现混淆。更高效可靠的方式是先对每个api_spec_id分组,一次性计算所有核心特征,再基于特征统计结果,避免重复操作。
修正后的代码
步骤1:分组计算每个ID的核心特征
按api_spec_id分组,一次性计算每个分组的四类关键特征:
# 分组计算核心特征,避免重复遍历数据集 group_stats = df.groupby('api_spec_id')['type'].agg( has_br=lambda x: x.isin(['BR']).any(), has_nbr=lambda x: x.isin(['NBR']).any(), all_br=lambda x: (x == 'BR').all(), all_nbr=lambda x: (x == 'NBR').all() )
步骤2:基于特征统计四类结果
# 1. 所有行type均为BR的api_spec_id数量 all_br_count = group_stats['all_br'].sum() # 2. 至少有一行type为BR的api_spec_id数量 at_least_one_br_count = group_stats['has_br'].sum() # 3. 至少有一行type为NBR的api_spec_id数量 at_least_one_nbr_count = group_stats['has_nbr'].sum() # 4. 所有行type均为NBR的api_spec_id数量 all_nbr_count = group_stats['all_nbr'].sum()
验证结果
运行后输出:
print(f"all_br_count = {all_br_count}") # 输出2(对应ID 678、123) print(f"at_least_one_br_count = {at_least_one_br_count}") # 输出3(对应ID 213、678、123) print(f"at_least_one_nbr_count = {at_least_one_nbr_count}") # 输出2(对应ID 213、345) print(f"all_nbr_count = {all_nbr_count}") # 输出1(对应ID 345)
注意:你的预期中all_commits_including_breaking = 3与实际数据不符,实际全为BR的ID仅2个,若此预期为笔误,上述代码可得到正确结果;若需求描述存在偏差,请调整特征计算逻辑。
替代简化写法
如果不需要保留分组特征,也可以直接通过过滤统计:
# 至少有一个BR的ID数量 at_least_one_br = df[df['type'] == 'BR']['api_spec_id'].nunique() # 全为BR的ID数量 all_br = df.groupby('api_spec_id').filter(lambda x: (x['type'] == 'BR').all())['api_spec_id'].nunique() # 至少有一个NBR的ID数量 at_least_one_nbr = df[df['type'] == 'NBR']['api_spec_id'].nunique() # 全为NBR的ID数量 all_nbr = df.groupby('api_spec_id').filter(lambda x: (x['type'] == 'NBR').all())['api_spec_id'].nunique()
内容的提问来源于stack exchange,提问作者Brie MerryWeather
相关产品推荐
相关产品推荐

