如何在Pandas中实现DataFrame区间关联与多规则分组聚合?
实现方法拆解
这是个很典型的Pandas区间关联+分组聚合场景,我来一步步给你拆解实现步骤:
1. 预处理数据
首先确保两个DataFrame的Section和Chainage列格式正确,并且按Section+Chainage排序,方便后续区间匹配:
import pandas as pd # 假设你已经加载好DataFrame1和DataFrame2,分别命名为df1、df2 df1 = df1.sort_values(['Section', 'Chainage']).reset_index(drop=True) df2 = df2.sort_values(['Section', 'Chainage']).reset_index(drop=True)
2. 为df1生成区间边界
因为df1的Chainage是5米间隔,我们给每一行添加对应的区间起始和结束值(这里默认区间是左闭右开,比如Chainage=0对应[0,5)的范围,你可以根据实际需求调整开闭方向):
df1['Chainage_Start'] = df1['Chainage'] df1['Chainage_End'] = df1['Chainage'] + 5
3. 按Section分组处理区间匹配与聚合
我们需要针对每个Section单独处理(避免不同Section的Chainage区间混淆),通过groupby+apply实现:
def process_single_section(group): # 获取当前处理的Section名称 current_section = group.name # 筛选df2中对应Section的数据 df2_subset = df2[df2['Section'] == current_section].copy() # 生成区间边界:用df1的起始值 + 最后一个区间的结束值 bins = pd.concat([group['Chainage_Start'], pd.Series([group['Chainage_End'].iloc[-1]])], ignore_index=True) # 用df1的Chainage值作为区间标签,方便后续关联 interval_labels = group['Chainage'] # 将df2的Chainage映射到对应的df1区间 df2_subset['Matching_Chainage'] = pd.cut( df2_subset['Chainage'], bins=bins, labels=interval_labels, include_lowest=True, # 确保第一个区间包含起始值 right=False # 左闭右开,若需要右闭左开则改为True ) # 关联df1的Frame列 df2_subset = df2_subset.merge( group[['Section', 'Chainage', 'Frame']], left_on=['Section', 'Matching_Chainage'], right_on=['Section', 'Chainage'], how='left' ) # 定义聚合规则:列1求和,列2取最大值,3-8取平均值,Frame取唯一值 agg_rules = { '1': 'sum', '2': 'max', '3': 'mean', '4': 'mean', '5': 'mean', '6': 'mean', '7': 'mean', '8': 'mean', 'Frame': 'first' # 每个区间对应唯一的Frame,取第一个即可 } # 执行聚合并整理结果 aggregated = df2_subset.groupby(['Section', 'Matching_Chainage', 'Frame']).agg(agg_rules).reset_index() aggregated.rename(columns={'Matching_Chainage': 'Chainage'}, inplace=True) return aggregated # 应用到所有Section,得到最终结果 final_result = df1.groupby('Section').apply(process_single_section).reset_index(drop=True)
关键注意事项
- 区间开闭调整:如果你的业务逻辑是右闭左开(比如Chainage=5属于5-10区间),只需把
pd.cut中的right参数改为True即可。 - 边界值处理:如果df2中存在超出df1最大Chainage+5的Chainage值,
pd.cut会将其标记为NaN,你可以根据需求添加过滤逻辑(比如df2_subset = df2_subset.dropna(subset=['Matching_Chainage']))。 - 非连续Chainage:如果df1的Chainage不是严格连续的5米间隔(比如存在缺失行),这个方法依然有效,因为区间是基于df1实际存在的Chainage值生成的。
内容的提问来源于stack exchange,提问作者user55641
相关产品推荐
相关产品推荐

