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

如何基于user_id键对两个Pandas DataFrame执行除法运算?

嘿,这个问题我之前处理类似需求时碰到过!其实不用折腾分组操作,Pandas有更简洁直接的方式解决,先给你理清楚思路:

首先先把两个示例DataFrame的代码贴出来,方便大家复现场景:

import pandas as pd

# 第一个包含用户、子项和得分的DataFrame
df1 = pd.DataFrame({
    'user_id': [39, 39, 40, 40, 40],
    'sub_id': [16, 4, 1, 2, 3],
    'score': [1, 1, 3, 3, 3]
})

# 第二个包含用户总得分的DataFrame
df2 = pd.DataFrame({
    'user_id': [39, 40],
    'score': [2, 30]
})

你说的用div操作只返回首个匹配项的问题,本质是因为div默认按索引对齐,而df2的索引是user_id,但df1的索引是默认的0、1、2...,只有df1中索引和df2索引(user_id)一致的行才能匹配上,其余自然返回NaN。

最简洁的解决方案:用map映射计算

先把df2转换成以user_id为键的Series,然后用df1的user_id列映射对应的用户总得分,最后做除法即可:

# 构建user_id到总得分的映射Series
user_total_scores = df2.set_index('user_id')['score']

# 逐行计算归一化得分
df1['normalized_score'] = df1['score'] / df1['user_id'].map(user_total_scores)

运行后得到的结果完全符合预期:

user_idsub_idscorenormalized_score
391610.5
39410.5
40130.1
40230.1
40330.1

备选方案:先合并再计算

如果需要保留df2中的其他列(假设后续有扩展需求),可以先通过merge按user_id合并两个DataFrame,再做除法:

# 合并两个DF,用后缀区分原得分和用户总得分
merged_df = df1.merge(df2, on='user_id', suffixes=('_sub', '_total'))

# 计算归一化得分
merged_df['normalized_score'] = merged_df['score_sub'] / merged_df['score_total']

# 整理回原df1的结构(可选)
result_df = merged_df[['user_id', 'sub_id', 'score_sub', 'normalized_score']].rename(columns={'score_sub': 'score'})

关于分组操作

分组当然也能实现,但代码更繁琐,性能也不如上面两种方法(数据量大时差距明显),这里也贴出来供你参考:

def normalize_group(group):
    # 获取当前分组对应的用户总得分
    total_score = df2.loc[df2['user_id'] == group.name, 'score'].iloc[0]
    group['normalized_score'] = group['score'] / total_score
    return group

result_df = df1.groupby('user_id').apply(normalize_group)

总结一下,优先用map的方法,简洁高效;merge适合有扩展需求的场景;分组操作除非特殊情况,否则没必要用~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:11:52