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

如何按相似非匹配值分组Pandas DataFrame?满足id、amount相同且num差值≤10

解决方案

要实现你描述的分组规则,核心是先按id和amount进行初步分组,再在每个子组内根据num的相邻差值(排序后)拆分出子分组,最后生成全局唯一的分组ID。以下是具体实现步骤:

1. 构造示例DataFrame

首先还原你提供的示例数据:

import pandas as pd

data = {
    'id': ['aaa-aaa', 'aaa-aaa', 'bbb-bbb', 'ccc-ccc', 'bbb-bbb', 'aaa-aaa', 'aaa-aaa'],
    'amount': [130, 130, 270, 130, 270, 130, 380],
    'num': [12, 39, 41, 19, 37, 42, 39]
}
df = pd.DataFrame(data)

2. 定义子分组分配函数

这个函数会处理每个(id, amount)组合的子数据集:

  • 先按num排序,确保能正确计算相邻值的差值
  • 判断相邻num的绝对值差是否超过10,超过则标记为新分组的起点
  • 累积求和生成子组内的分组编号
def assign_subgroup(sub_df):
    # 按num排序,保证差值计算的合理性
    sorted_sub = sub_df.sort_values('num').reset_index(drop=True)
    # 计算相邻num的绝对值差,第一行差值为NaN
    num_diff = sorted_sub['num'].diff().abs()
    # 标记新分组的起点:第一行 或 差值超过10
    new_group_flag = (num_diff > 10) | num_diff.isna()
    # 累积求和得到子组内的分组ID
    sorted_sub['sub_group'] = new_group_flag.cumsum()
    # 合并回原数据,保留原始行顺序
    return sub_df.merge(sorted_sub[['num', 'sub_group']], on='num', how='left')

3. 应用分组并生成全局分组ID

对原DataFrame按id和amount分组,应用上述函数,再将(id, amount, sub_group)的组合映射为全局唯一的分组编号:

# 为每个(id, amount)子组分配子分组ID
df_with_subgroup = df.groupby(['id', 'amount'], group_keys=False).apply(assign_subgroup)

# 生成全局分组ID映射
unique_groups = df_with_subgroup[['id', 'amount', 'sub_group']].drop_duplicates()
group_mapping = {tuple(row): idx+1 for idx, row in enumerate(unique_groups.itertuples(index=False))}

# 为每行分配全局分组ID
df_with_subgroup['group_id'] = df_with_subgroup.apply(
    lambda x: group_mapping[(x['id'], x['amount'], x['sub_group'])],
    axis=1
)

4. 查看结果

执行后,df_with_subgroup中的group_id列就是你需要的分组编号,输出结果如下:

id  amount  num  sub_group  group_id
0  aaa-aaa     130   12          1         1
1  aaa-aaa     130   39          2         2
2  bbb-bbb     270   41          1         3
3  ccc-ccc     130   19          1         4
4  bbb-bbb     270   37          1         3
5  aaa-aaa     130   42          2         2
6  aaa-aaa     380   39          1         5

完全符合你预期的分组规则:

  • 分组1:仅含aaa-aaa、130、12的行
  • 分组2:含aaa-aaa、130、39和42的行
  • 分组3:含bbb-bbb、270、41和37的行
  • 分组4:仅含ccc-ccc、130、19的行
  • 分组5:仅含aaa-aaa、380、39的行

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 21:17:49