按变量分组计算两个不同DataFrame中集合的交集
我来帮你搞定按分组计算两个DataFrame交集的需求,先把你的示例数据整理清楚,再分场景给出实现方案:
你的示例数据
先把两个DataFrame用表格直观展示:
setA
| session_id | datetime | request |
|---|---|---|
| 1105 | 2016-03-09 00:33:42 | 8 |
| 1105 | 2016-03-09 00:33:43 | 3 |
| 1107 | 2016-03-09 00:44:24 | 14 |
| 1107 | 2016-03-09 00:44:26 | 14 |
| 1108 | 2016-03-09 00:54:02 | 9 |
| 1108 | 2016-03-09 00:54:04 | 10 |
| 1109 | 2016-03-09 01:01:37 | 17 |
| 1109 | 2016-03-09 01:01:39 | 6 |
| 1110 | 2016-03-09 01:02:49 | 10 |
| 1110 | 2016-03-09 01:02:49 | 8 |
setB
| session_id | datetime | request |
|---|---|---|
| 1105 | 2016-03-09 00:33:45 | ... |
(注:这里setB的request值用...表示未完整给出,下面的方案会基于通用场景演示)
两种常见场景的实现方案
假设我们按session_id分组,分两种交集需求来处理:
场景1:找每个session下完全匹配的行(session_id+datetime+request都一致)
这种需求可以直接用pandas.merge来实现,它会自动帮我们筛选出两个DataFrame中完全匹配的行,之后再按session分组查看即可:
import pandas as pd # 先构造你的示例数据(模拟setA和setB) data_setA = { 'session_id': [1105,1105,1107,1107,1108,1108,1109,1109,1110,1110], 'datetime': ['2016-03-09 00:33:42','2016-03-09 00:33:43','2016-03-09 00:44:24','2016-03-09 00:44:26','2016-03-09 00:54:02','2016-03-09 00:54:04','2016-03-09 01:01:37','2016-03-09 01:01:39','2016-03-09 01:02:49','2016-03-09 01:02:49'], 'request': [8,3,14,14,9,10,17,6,10,8] } setA = pd.DataFrame(data_setA) setA['datetime'] = pd.to_datetime(setA['datetime']) # 确保datetime是时间类型 # 模拟setB的完整数据(假设request值为3) data_setB = { 'session_id': [1105], 'datetime': ['2016-03-09 00:33:43'], # 修改成和setA匹配的时间来演示 'request': [3] } setB = pd.DataFrame(data_setB) setB['datetime'] = pd.to_datetime(setB['datetime']) # 计算行交集:inner join只会保留完全匹配的行 intersection_rows = pd.merge(setA, setB, on=['session_id', 'datetime', 'request'], how='inner') # 按session_id分组展示结果 grouped_result = intersection_rows.groupby('session_id').apply(lambda df: df) print(grouped_result)
运行后会输出session_id=1105下匹配的那一行数据。
场景2:找每个session下request值的集合交集(不考虑datetime)
如果只关心每个session对应的request值的交集,不需要匹配时间,可以用分组后转集合再求交集的方式:
# 按session_id分组,提取每个session的request集合 setA_request_sets = setA.groupby('session_id')['request'].apply(set) setB_request_sets = setB.groupby('session_id')['request'].apply(set) # 先找到两个DataFrame共有的session_id common_sessions = set(setA_request_sets.index) & set(setB_request_sets.index) # 遍历共同session,计算request的集合交集 session_request_intersections = {} for session in common_sessions: session_request_intersections[session] = setA_request_sets[session] & setB_request_sets[session] # 转成DataFrame方便查看 result_df = pd.DataFrame.from_dict(session_request_intersections, orient='index', columns=['request_intersection']) result_df.index.name = 'session_id' print(result_df)
比如如果setB中session_id=1105的request包含3,结果就会显示该session的交集为{3}。
小提示
- 一定要确保
datetime列是datetime类型,否则字符串匹配可能会出问题,用pd.to_datetime()转换是必要步骤。 - 如果你的交集定义是其他维度(比如只匹配session_id和datetime),只需要调整
merge的on参数,或者修改集合提取的列即可。
内容的提问来源于stack exchange,提问作者SumitArya
相关产品推荐
相关产品推荐

