列数不一致的DataFrame关联:按Hour与Type匹配Total #Users
解决DataFrame关联匹配Total #Users字段的问题
当然可以实现你的需求,而且有两种常用方案——既可以用你提到的map方法,也可以用更直观的merge方法,我结合你的示例给你详细说明:
先看你的示例数据
DF1(细粒度数据)
| Source | #Users | #Clicks | Hour | Type |
|---|---|---|---|---|
| Prod1 | 50 | 3 | 01 | Internet |
| Prod2 | 10 | 2 | 07 | iOS |
| Prod3 | 1 | 50 | 07 | Internet |
| Prod2 | 3 | 2 | 07 | Internet |
| Prod3 | 8 | 2 | 05 | Internet |
DF2(汇总数据)
| Type | Total #Users | Hour |
|---|---|---|
| Internet | 100 | 01 |
| iOS | 500 | 01 |
| Internet | 300 | 07 |
| Internet | 15 | 05 |
| iOS | 20 | 07 |
期望结果
| Source | #Users | #Clicks | Hour | Type | Total #Users |
|---|---|---|---|---|---|
| Prod1 | 50 | 3 | 01 | Internet | 100 |
| Prod2 | 10 | 2 | 07 | iOS | 20 |
| Prod3 | 1 | 50 | 07 | Internet | 300 |
| Prod2 | 3 | 2 | 07 | Internet | 300 |
| Prod3 | 8 | 2 | 05 | Internet | 15 |
方案一:使用Pandas的merge方法(推荐)
这是最直观的方式,因为你需要同时基于Hour和Type两个字段进行关联(DF2的Total #Users是按这两个维度汇总的),直接用merge就能一步到位:
import pandas as pd # 假设你已经有df1和df2两个DataFrame result_df = pd.merge(df1, df2, on=['Hour', 'Type'], how='left')
on=['Hour', 'Type']:指定关联的键是这两个字段,确保每个DF1的行都能匹配到DF2中对应Hour+Type组合的Total #Usershow='left':保留DF1的所有行,即使DF2中没有匹配项(这种情况Total #Users会显示NaN,你可以根据需求处理)
运行这段代码后,得到的result_df就是你想要的结构,和期望结果完全一致。
方案二:使用map方法
当然可以用map,不过需要先把DF2转换成一个以**(Hour, Type)**为键、Total #Users为值的字典,然后让DF1通过这个字典映射出对应的数值:
# 先把DF2转成字典:键是(Hour, Type)元组,值是Total #Users total_users_map = df2.set_index(['Hour', 'Type'])['Total #Users'].to_dict() # 在DF1中新增Total #Users字段,通过(Hour, Type)元组映射 df1['Total #Users'] = df1.apply(lambda row: total_users_map.get((row['Hour'], row['Type'])), axis=1) # 最终df1就是你要的结果 result_df = df1
这里要注意:必须确保DF2中每个(Hour, Type)组合是唯一的,否则转字典的时候后面的值会覆盖前面的(你的示例里是唯一的,所以没问题)。如果有重复组合,建议先对DF2做去重或者聚合处理。
两种方案对比
merge方法:代码简洁、可读性高,适合大多数场景,新手也容易理解,而且能自动处理可能的匹配缺失情况map方法:如果你的数据量极大,map的性能可能会略好一点,但需要额外处理字典的构建,对键的唯一性要求高
内容的提问来源于stack exchange,提问作者Russel Wilcox-Cline
相关产品推荐
相关产品推荐

