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

基于动态条件对DataFrame数据进行分组打标签的技术求助

基于动态条件为DataFrame用户批量打标签的解决方案

我来帮你搞定这个按动态规则给DataFrame用户分组打标签的需求,咱们先理清楚需求细节,再给出可运行的实现代码。


初始数据集(df3)

首先是你提供的第一个测试数据集:

import pandas as pd
df3 = pd.DataFrame({ 
    'first_name': ['John', 'John', 'Jane', 'Jane', 'Jane','Marry', 'Victoria', 'Gabriel', 'John'], 
    'id': [1, 1, 2, 2, 2, 3, 4, 5, 1], 
    'age': [30, 30, 25, 25, 25, 30, 45, 15, 30], 
    'group': [0, 0, 0, 0, 0, 0, 0, 0, 0], 
    'product_type': [1, 1, 2, 1, 2, 1, 2, 1, 2], 
    'quantity': [10, 15, 10, 10, 15, 30, 30, 10, 10] 
})
df3['agemore'] = (df3['age'] > 20)

核心分组规则

你需要按照以下逻辑为用户(按id区分)标记group值:

  1. 优先选取当前group=0中id最小的用户,先将其所有行标记为当前分组号(初始为1);
  2. 提取该用户agemore=True、按product_type分组后的排序后quantity列表作为匹配特征;
  3. 查找所有未分组的用户,若该用户满足agemore=True,且其某类product_type对应的排序后quantity列表与目标用户的任意一个特征列表匹配,则将该用户也标记为当前分组号;
  4. 递增分组号,重复上述步骤,直到所有用户都完成分组。

(注:根据你给出的示例,id=1的product_type=1对应quantity[10,15],id=2的product_type=2对应quantity[10,15],二者匹配,因此归为同一组)

预期输出(df4)

最终分组后的结果应该是这样的:

df4 = pd.DataFrame({ 
    'first_name': ['John', 'John', 'Jane', 'Jane', 'Jane','Marry', 'Victoria', 'Gabriel', 'John'], 
    'id': [1, 1, 2, 2, 2, 3, 4, 5, 1], 
    'age': [30, 30, 25, 25, 25, 30, 45, 15, 30], 
    'group': [1, 1, 1, 1, 1, 2, 2, 3, 1], 
    'product_type': [1, 1, 2, 1, 2, 1, 2, 1, 2], 
    'quantity': [10, 15, 10, 10, 15, 30, 30, 10, 10] 
})

第二个测试数据集(set2)

你还提供了第二个测试数据集用于验证:

import pandas as pd
data = pd.DataFrame({ 
    'first_name': ['John', 'John', 'Jane', 'Jane', 'Jane','Marry', 'Victoria', 'Gabriel', 'John'], 
    'id': [1, 1, 2, 2, 2, 3, 4, 5, 1], 
    'age': [30, 30, 25, 25, 25, 30, 45, 15, 3], 
    'group': [0, 0, 0, 0, 0, 0, 0, 0, 0], 
    'product_type': [1, 1, 2, 1, 2, 1, 2, 1, 1], 
    'quantity': [10, 15, 10, 10, 15, 30, 30, 10, 10] 
})
data['agemore'] = (data['age'] > 20)

实现代码

下面是完全符合需求的Python代码,包含详细注释:

def assign_dynamic_groups(df):
    # 复制原数据,避免修改原始输入
    df_processed = df.copy()
    current_group_num = 1
    
    # 获取所有唯一用户id,按升序排列,方便后续取最小未分组id
    all_unique_ids = sorted(df_processed['id'].unique())
    
    while True:
        # 筛选出当前未分组的用户id(group=0)
        ungrouped_ids = [user_id for user_id in all_unique_ids 
                         if df_processed[df_processed['id'] == user_id]['group'].iloc[0] == 0]
        
        if not ungrouped_ids:
            break  # 所有用户都已分组,退出循环
        
        # 取当前未分组中id最小的用户作为目标用户
        target_id = min(ungrouped_ids)
        target_user_data = df_processed[df_processed['id'] == target_id]
        
        # 标记目标用户为当前分组
        df_processed.loc[df_processed['id'] == target_id, 'group'] = current_group_num
        
        # 提取目标用户的匹配特征:agemore=True时,按product_type分组的排序后quantity列表
        target_features = (target_user_data[target_user_data['agemore'] == True]
                          .groupby('product_type')['quantity']
                          .apply(lambda x: sorted(x.tolist()))
                          .to_dict())
        target_quant_lists = list(target_features.values())
        
        # 遍历其他未分组用户,进行特征匹配
        for compare_id in ungrouped_ids[1:]:
            compare_user_data = df_processed[df_processed['id'] == compare_id]
            
            # 跳过agemore全为False的用户(按规则要求agemore=True)
            if not compare_user_data['agemore'].any():
                continue
            
            # 提取待匹配用户的特征
            compare_features = (compare_user_data[compare_user_data['agemore'] == True]
                               .groupby('product_type')['quantity']
                               .apply(lambda x: sorted(x.tolist()))
                               .to_dict())
            compare_quant_lists = list(compare_features.values())
            
            # 检查是否存在匹配的quantity列表
            if any(quant_list in compare_quant_lists for quant_list in target_quant_lists):
                # 匹配成功,标记为当前分组
                df_processed.loc[df_processed['id'] == compare_id, 'group'] = current_group_num
        
        # 分组号递增,处理下一组
        current_group_num += 1
    
    return df_processed

# 测试第一个数据集
df4 = assign_dynamic_groups(df3)
print("第一个数据集分组结果:")
print(df4)

# 测试第二个数据集
data_grouped = assign_dynamic_groups(data)
print("\n第二个数据集分组结果:")
print(data_grouped)

代码关键点说明

  1. 数据安全:先复制原数据,避免修改原始输入;
  2. 循环逻辑:持续找到最小未分组用户,直到所有用户完成分组;
  3. 特征提取:针对agemore=True的行,按product_type提取排序后的quantity列表,确保匹配不受顺序影响;
  4. 匹配规则:检查待匹配用户是否有任意一组quantity列表与目标用户的特征列表一致,同时满足agemore=True的条件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 18:12:28