如何合并多列DataFrame并拆分行?
如何合并多列DataFrame并拆分行?
看起来你需要把两个区间型的DataFrame合并,把那些互相重叠的大区间拆分成连续的小区间,同时算出每个小区间对应的int值。我来一步步教你搞定这个需求:
步骤1:收集所有区间分界点
首先我们要把两个DataFrame里所有的from和to值都收集起来,去重后排序,这些点就是拆分小区间的核心分界点:
import pandas as pd # 你的原始数据 df1 = pd.DataFrame({ 'from': [0, 2, 8, 26, 35, 46], 'to': [2, 8, 26, 35, 46, 48], 'int': [2, 6, 18, 9, 11, 2]}) df2 = pd.DataFrame({ 'from': [0, 2, 8, 17, 34], 'to': [2, 8, 17, 34, 49], 'int': [2, 6, 9, 17, 15]}) # 收集所有分界点并排序 all_points = sorted(set(df1['from'].tolist() + df1['to'].tolist() + df2['from'].tolist() + df2['to'].tolist()))
步骤2:生成拆分后的小区间
用这些分界点生成连续的小区间,每个区间就是相邻两个点的组合:
# 构建新的区间DataFrame new_df = pd.DataFrame({ 'from': all_points[:-1], 'to': all_points[1:] })
步骤3:匹配每个小区间对应的原始int值
接下来要给每个小区间找到它在df1和df2中所属的父区间的int值。这里用merge_asof最适合——因为你的原始区间都是不重叠且按顺序排列的,这个工具能精准匹配到对应父区间:
# 先对原始DataFrame按from排序(确保merge_asof正常工作) df1_sorted = df1.sort_values('from') df2_sorted = df2.sort_values('from') # 匹配df1中的对应int值 new_df = pd.merge_asof( new_df, df1_sorted, left_on='from', right_on='from', direction='backward' # 找小于等于当前from的最后一个有效区间 ) # 匹配df2中的对应int值,用后缀区分两个来源的int new_df = pd.merge_asof( new_df, df2_sorted, left_on='from', right_on='from', direction='backward', suffixes=('_df1', '_df2') ) # 处理那些不在原始DataFrame覆盖范围内的区间,把int设为0 new_df['int_df1'] = new_df['int_df1'].fillna(0) new_df['int_df2'] = new_df['int_df2'].fillna(0)
步骤4:计算目标int值
观察你给出的结果,每个小区间的int是该区间在df1中的int贡献减去df2中的int贡献。因为你的原始数据里int刚好等于区间长度,我们可以按比例把父区间的int分配到小区间:
# 计算每个小区间的长度 new_df['length'] = new_df['to'] - new_df['from'] # 计算df1中该小区间的int贡献:(父区间int / 父区间长度) * 小区间长度 new_df['contribution_df1'] = (new_df['int_df1'] / (new_df['to_df1'] - new_df['from_df1'])) * new_df['length'] # 计算df2中该小区间的int贡献 new_df['contribution_df2'] = (new_df['int_df2'] / (new_df['to_df2'] - new_df['from_df2'])) * new_df['length'] # 计算目标int值,和你的示例结果完全一致 new_df['int'] = new_df['contribution_df1'] - new_df['contribution_df2'] # 保留需要的列并转换为整数 final_df = new_df[['from', 'to', 'int']].astype(int)
运行后得到的final_df就是你想要的结果:
from to int 0 0 2 2 1 2 8 6 2 8 17 9 3 17 26 9 4 26 34 8 5 34 35 1 6 35 46 11 7 46 48 2 8 48 49 1
备注:内容来源于stack exchange,提问作者BRat
相关产品推荐
相关产品推荐

