Pandas按两DataFrame区间重叠映射列并对匹配值求和
解决Pandas双数据集区间重叠匹配求和问题
区间重叠判断的核心逻辑:两个区间存在重叠的充要条件是 df1.Start < df2.End 且 df1.End > df2.Start,完全包含、部分重叠的场景都能覆盖,以下分两种数据量场景给出实现方案:
方案1:小数据量场景(万行级别以下)
用交叉连接+条件筛选实现,写法简单直观:
import pandas as pd # 给df1加唯一行标识,方便后续分组对齐 df1 = df1.reset_index(names='df1_id') # 生成两个表的笛卡尔积 cross_df = df1.merge(df2, how='cross') # 筛选出存在区间重叠的匹配行 overlap_df = cross_df[(cross_df['Start_x'] < cross_df['End_y']) & (cross_df['End_x'] > cross_df['Start_y'])] # 按df1行分组求和Num,合并回原df1 result = df1.merge( overlap_df.groupby('df1_id')['Num'].sum().reset_index(name='Matched_Num'), on='df1_id', how='left' ).fillna({'Matched_Num': 0}) # 无匹配的行填充0,不需要可删除该行 # 删除临时标识列 result = result.drop(columns='df1_id')
方案2:大数据量场景
用pandas.IntervalIndex做重叠查询,性能远高于交叉连接:
# 将df2的区间转为IntervalIndex,closed参数根据你区间的开闭规则调整,可选left/right/both/neither df2_intervals = pd.IntervalIndex.from_arrays(df2['Start'], df2['End'], closed='both') # 逐行匹配重叠区间并求和 def calc_matched_num(row): current_interval = pd.Interval(row['Start'], row['End'], closed='both') overlap_mask = df2_intervals.overlaps(current_interval) return df2.loc[overlap_mask, 'Num'].sum() df1['Matched_Num'] = df1.apply(calc_matched_num, axis=1)
注意:如果区间开闭规则和示例不同,仅需修改
closed参数即可对齐业务逻辑。
内容的提问来源于stack exchange,提问作者Alicia Pliego
相关产品推荐
相关产品推荐

