基于相同键值匹配计算不同大小DataFrame占比的问题排查
解决DataFrame周计数占总计数百分比计算问题
问题场景
有两个DataFrame:
- 周计数表:存储指定年月的分周计数
- 总计数表:存储对应年月的分组总计数
需要计算每组周计数占总计数的百分比。
示例总计数DataFrame
import pandas as pd total_dataframe = pd.DataFrame({ 'Col1': ['A','A','A'], 'Col2': ['B1','B2','B3'], 'Total_Counts': [10,20,30] })
输出:
Col1 Col2 Total_Counts 0 A B1 10 1 A B2 20 2 A B3 30
示例周计数DataFrame
weekly_dataframe = pd.DataFrame({ 'Col1': ['A','A','A','A','A','A','A','A','A'], 'Col2': ['B1','B2','B3','B1','B2','B3','B1','B2','B3'], 'Weekly_Counts': [1,4,6,10,4,6,12,12,6] })
输出:
Col1 Col2 Weekly_Counts 0 A B1 1 1 A B2 4 2 A B3 6 3 A B1 10 4 A B2 4 5 A B3 6 6 A B1 12 7 A B2 12 8 A B3 6
问题分析
你尝试用merge合并后计算百分比,但出现两个问题:
- 生成的
Percentage列全为NaN - 合并后出现
Total_Counts_x和Total_Counts_y重复列,修改后结果仍不符合预期
核心原因:
- 列名不匹配:
assign生成的列名为new,但reindex指定的是Percentage,导致该列不存在,全为NaN - 重复列冲突:你的两个DataFrame可能都包含
Total_Counts列,merge时自动添加后缀区分,此时未明确使用总计数表的对应列
修正方案
方案1:针对示例无重复列的场景
直接修正列名匹配问题,合并时左右键名相同可简化为on参数:
result = (weekly_dataframe.merge(total_dataframe, on=['Col1', 'Col2'], how='left') .assign(Percentage=lambda x: round(x['Weekly_Counts'].div(x['Total_Counts']) * 100, 2)) .reindex(columns=[*weekly_dataframe.columns, 'Percentage']))
输出结果(部分):
Col1 Col2 Weekly_Counts Percentage 0 A B1 1 10.0 3 A B1 10 100.0 6 A B1 12 120.0
方案2:针对存在重复列的场景
如果周计数表也有Total_Counts列,可通过指定后缀或重命名列避免冲突:
方法A:指定合并后缀
result = (weekly_dataframe.merge(total_dataframe, on=['Col1', 'Col2'], how='left', suffixes=('_weekly', '_total')) # 给重复列加区分后缀 .assign(Percentage=lambda x: round(x['Weekly_Counts'].div(x['Total_Counts_total']) * 100, 2)) .reindex(columns=[*weekly_dataframe.columns, 'Percentage']))
方法B:先重命名总计数表列
# 重命名总计数表的Total_Counts列,避免合并冲突 total_renamed = total_dataframe.rename(columns={'Total_Counts': 'Total_Counts_Total'}) result = (weekly_dataframe.merge(total_renamed, on=['Col1', 'Col2'], how='left') .assign(Percentage=lambda x: round(x['Weekly_Counts'].div(x['Total_Counts_Total']) * 100, 2)) .reindex(columns=[*weekly_dataframe.columns, 'Percentage']))
内容的提问来源于stack exchange,提问作者Chronicles
相关产品推荐
相关产品推荐

