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

基于多列条件统计相似实例:标签与特征变化计数需求

问题与解决方案

问题描述

现有如下DataFrame:

api_spec_id commit_date   label           F1       F2     F3     F4      F5
1           2019-01-01    major            1        3      4      7      0
1           2019-04-05    patch            1        3      4      7      0
1           2019-10-09                     4        4      2      6      9          
2           2020-03-01    major.minor      1        9      4      5      5
2           2020-03-05                     3        6      2      1      8
2           2021-04-01                     3        6      2      1      8

需要统计两类实例的数量:

  • 标签相同但特征(F1、F2、F3、F4、F5)变化的实例
  • 标签变化但特征相同的实例

注:空标签行表示标签未发生变化,即沿用前一行的标签。

预期输出:

same_label_diff_features = 2 ( labels same, features change)
diff_label_same_features = 1 ( labels change, features same)

尝试了以下代码但方法不正确:

same_label_diff_features = (pd.pivot_table(df_2015.iloc[:, 2:], index='_label', aggfunc=pd.Series.nunique)
                            .gt(1).sum(axis=0).sum())

求更优解决方案。


解决方案

首先要明确:空标签表示继承前一行的标签,所以第一步必须先补全这些空值,否则无法准确统计。

1. 补全空标签

用ffill()向前填充空标签,确保每个行都有明确的标签:

df['label'] = df['label'].ffill()

补全后的数据如下:

api_spec_id commit_date       label  F1  F2  F3  F4  F5
1           2019-01-01        major   1   3   4   7   0
1           2019-04-05        patch   1   3   4   7   0
1           2019-10-09        patch   4   4   2   6   9
2           2020-03-01  major.minor   1   9   4   5   5
2           2020-03-05  major.minor   3   6   2   1   8
2           2021-04-01  major.minor   3   6   2   1   8

2. 统计两类实例

统计的核心是按api_spec_id分组,因为变化只需要在同一个API规格下比较。

统计「标签变化但特征相同」的实例数

思路:同一api_spec_id下,如果一组完全相同的特征对应了不同的标签,就属于这类情况。按api_spec_id+特征列分组,统计每组内的标签数量,若数量>1则计数:

feature_cols = ['F1', 'F2', 'F3', 'F4', 'F5']
# 分组统计每组的标签种类数
label_counts = df.groupby(['api_spec_id'] + feature_cols)['label'].nunique()
# 筛选出标签种类数>1的组,求和得到总数
diff_label_same_features = (label_counts > 1).sum()

统计「标签相同但特征变化」的实例数

思路:同一api_spec_id+label下,如果存在不同的特征组合,每新增一种不同的组合就算一次变化(比如3个不同组合对应2次变化)。按api_spec_id+label分组,统计每组内不同特征组合的数量,再用(数量-1)求和:

# 按分组统计每组内唯一特征组合的数量,计算变化次数后求和
same_label_diff_features = (df.groupby(['api_spec_id', 'label'])[feature_cols]
                           .apply(lambda x: x.drop_duplicates().shape[0] - 1)).sum()

完整可运行代码

import pandas as pd

# 构造示例数据
data = {
    'api_spec_id': [1,1,1,2,2,2],
    'commit_date': ['2019-01-01','2019-04-05','2019-10-09','2020-03-01','2020-03-05','2021-04-01'],
    'label': ['major','patch','','major.minor','',''],
    'F1': [1,1,4,1,3,3],
    'F2': [3,3,4,9,6,6],
    'F3': [4,4,2,4,2,2],
    'F4': [7,7,6,5,1,1],
    'F5': [0,0,9,5,8,8]
}
df = pd.DataFrame(data)

# 补全空标签
df['label'] = df['label'].ffill()
feature_cols = ['F1', 'F2', 'F3', 'F4', 'F5']

# 计算标签变化但特征相同的数量
diff_label_same_features = (df.groupby(['api_spec_id'] + feature_cols)['label'].nunique() > 1).sum()

# 计算标签相同但特征变化的数量
same_label_diff_features = (df.groupby(['api_spec_id', 'label'])[feature_cols]
                           .apply(lambda x: x.drop_duplicates().shape[0] - 1)).sum()

# 输出结果
print(f"same_label_diff_features = {same_label_diff_features} ( labels same, features change)")
print(f"diff_label_same_features = {diff_label_same_features} ( labels change, features same)")

运行后输出与预期完全一致:

same_label_diff_features = 2 ( labels same, features change)
diff_label_same_features = 1 ( labels change, features same)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 14:52:25