You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何合并多列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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 14:38:00