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

Pandas Merge操作中CampCount列被UnitCount覆盖的问题排查

问题描述

需求是统计单元总数、标记为'Y'的活动单元数,并计算两者的比值。但执行merge操作时,CampCount列出现NaN值,还存在匹配错误(如CAMPAIGN_PROFILE_x为'N'但CAMPAIGN_PROFILE_y为'Y')。

使用的代码如下:

def campaign_sorter(x, y):
    new_df = x[['VFMFRC', 'VFUNIT', 'IS_MONTH', 'IS_DAYS_GROUP', 'CAMPAIGN_PROFILE']].copy()

    # Counting distinct unit numbers by IS_MONTH, IS_DAYS_GROUP, and other columns
    unit_count = new_df.groupby(['IS_MONTH', 'IS_DAYS_GROUP', 'VFMFRC', 'CAMPAIGN_PROFILE']).agg({'VFUNIT': 'nunique'}).reset_index()
    unit_count.columns = ['IS_MONTH', 'IS_DAYS_GROUP', 'VFMFRC', 'CAMPAIGN_PROFILE', 'UnitCount']

    # Counting distinct comp code values by IS_MONTH, IS_DAYS_GROUP, and other columns
    camp_count = new_df[new_df['CAMPAIGN_PROFILE'] == 'Y'].groupby(['IS_MONTH', 'IS_DAYS_GROUP', 'VFMFRC', 'CAMPAIGN_PROFILE']).agg({'VFUNIT': 'nunique'}).reset_index()
    camp_count.columns = ['IS_MONTH', 'IS_DAYS_GROUP', 'VFMFRC', 'CAMPAIGN_PROFILE', 'CampCount']

    # Merging the unit counts and comp code counts DataFrames
    merged_df = pd.merge(unit_count, camp_count, on=['IS_MONTH', 'IS_DAYS_GROUP', 'VFMFRC', 'CAMPAIGN_PROFILE'], how='left', suffixes=('_unit', '_comp'))

    # Calculating the RPU (Ratio of Unit Count to Comp Code Count)
    # merged_df['RPU'] = merged_df['UnitCount'] / merged_df['CampCount']


    # Merging the RPU values with the original dataframe
    # new_df = pd.merge(new_df, merged_df[['IS_MONTH', 'IS_DAYS_GROUP', 'VFMFRC', 'CAMPAIGN_PROFILE', 'RPU']], on=['IS_MONTH', 'IS_DAYS_GROUP', 'VFMFRC', 'CAMPAIGN_PROFILE'], how='left')

    # Dropping unnecessary columns and removing duplicates
    # new_df = new_df.drop(columns=['IS_MONTH']).drop_duplicates()

    return merged_df

已知unit_count输出60行,camp_count输出24行。


问题分析与解决

错误原因

  1. 分组键逻辑偏差:统计unit_count时,你把CAMPAIGN_PROFILE加入了分组键,导致unit_count被拆分为CAMPAIGN_PROFILE='Y'和='N'的子组;而camp_count只筛选了CAMPAIGN_PROFILE='Y'的数据并按该字段分组,merge时unit_count中CAMPAIGN_PROFILE='N'的行无法匹配,直接出现CampCount=NaN。
  2. 需求匹配错误:你的核心需求是每个分组(IS_MONTH/IS_DAYS_GROUP/VFMFRC)下的总单元数和该分组内标记为Y的单元数,但原代码按CAMPAIGN_PROFILE拆分统计,完全偏离了需求逻辑。

修正方案

  • 统计unit_count时,仅按IS_MONTH、IS_DAYS_GROUP、VFMFRC分组,计算该分组下所有唯一单元的总数。
  • 统计camp_count时,同样按上述三个字段分组,计算该分组内CAMPAIGN_PROFILE='Y'的唯一单元数,无需将CAMPAIGN_PROFILE加入分组键。
  • merge时仅用三个核心分组键连接,确保每组的总单元数和Y单元数正确匹配。

修改后的代码

def campaign_sorter(x, y):
    new_df = x[['VFMFRC', 'VFUNIT', 'IS_MONTH', 'IS_DAYS_GROUP', 'CAMPAIGN_PROFILE']].copy()

    # 统计每个分组下的总唯一单元数(不区分CAMPAIGN_PROFILE)
    unit_count = new_df.groupby(['IS_MONTH', 'IS_DAYS_GROUP', 'VFMFRC']).agg({'VFUNIT': 'nunique'}).reset_index()
    unit_count.columns = ['IS_MONTH', 'IS_DAYS_GROUP', 'VFMFRC', 'UnitCount']

    # 统计每个分组下标记为'Y'的唯一单元数
    camp_filtered = new_df[new_df['CAMPAIGN_PROFILE'] == 'Y']
    camp_count = camp_filtered.groupby(['IS_MONTH', 'IS_DAYS_GROUP', 'VFMFRC']).agg({'VFUNIT': 'nunique'}).reset_index()
    camp_count.columns = ['IS_MONTH', 'IS_DAYS_GROUP', 'VFMFRC', 'CampCount']

    # 按核心分组键合并,缺失的CampCount填充为0(表示该分组无Y标记的单元)
    merged_df = pd.merge(unit_count, camp_count, on=['IS_MONTH', 'IS_DAYS_GROUP', 'VFMFRC'], how='left').fillna({'CampCount': 0})

    # 计算比值(避免除以0,将0替换为NaN)
    merged_df['RPU'] = merged_df['UnitCount'] / merged_df['CampCount'].replace(0, float('nan'))

    return merged_df

额外说明

  • 用fillna({'CampCount':0})处理无Y标记的分组,避免后续计算报错;计算比值时用replace(0, float('nan')),避免出现无穷大值。
  • 若需要将结果合并回原数据,直接用new_df和merged_df按三个分组键merge即可,无需保留CAMPAIGN_PROFILE作为连接键。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 22:15:29