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

如何基于A列+From/To列合并两个Pandas DataFrame?

Pandas 基于区间重叠的合并方案

要实现你需要的合并逻辑,核心是基于时间区间的重叠匹配,再结合相邻同属性区间的合并,最终得到目标结果。以下是具体实现步骤和代码:

步骤说明

  1. 日期格式标准化:把字符串类型的日期转成datetime,避免字符串比较的误差。
  2. 生成子区间:收集两个表中所有的时间节点,排序后拆分出连续的子区间,确保覆盖所有可能的重叠范围。
  3. 匹配区间对应的属性值:对每个子区间,找到所有覆盖它的A表记录的B值和B表记录的C值,生成组合记录。
  4. 合并相邻重复区间:将相邻且B、C值完全相同的区间合并,简化结果。

完整代码

import pandas as pd

def format_date(dt):
    """把datetime对象转成原示例的日期字符串格式(如'1-1-2024')"""
    return f"{dt.day}-{dt.month}-{dt.year}"

# 加载原始数据
data_a = {
    'From': ['1-1-2024', '2-2-2024'],
    'To': ['1-1-9999', '1-1-9999'],
    'A': ['XX', 'XX'],
    'B': ['YY', 'ZZ']
}
a = pd.DataFrame(data_a)

data_b = {
    'From': ['1-1-2024', '16-1-2024'],
    'To': ['15-1-2024', '1-1-9999'],
    'A': ['XX', 'XX'],
    'C': ['LL', 'OO']
}
b = pd.DataFrame(data_b)

# 1. 转换日期列为datetime类型
a['From'] = pd.to_datetime(a['From'], dayfirst=True)
a['To'] = pd.to_datetime(a['To'], dayfirst=True)
b['From'] = pd.to_datetime(b['From'], dayfirst=True)
b['To'] = pd.to_datetime(b['To'], dayfirst=True)

# 2. 收集所有时间节点并生成子区间
all_dates = pd.concat([a['From'], a['To'], b['From'], b['To']]).unique()
all_dates = sorted(all_dates)
intervals = [(all_dates[i], all_dates[i+1]) for i in range(len(all_dates)-1)]

# 3. 遍历子区间,匹配对应的B和C值
result = []
for s, e in intervals:
    # 筛选A表中与当前子区间有非零重叠的记录
    a_matches = a[(a['From'] < e) & (a['To'] > s)]['B'].unique()
    # 筛选B表中与当前子区间有非零重叠的记录
    b_matches = b[(b['From'] < e) & (b['To'] > s)]['C'].unique()
    
    # 跳过无匹配的区间
    if len(a_matches) == 0 or len(b_matches) == 0:
        continue
    
    # 生成B和C的所有组合
    for b_val in a_matches:
        for c_val in b_matches:
            result.append({
                'From': s,
                'To': e,
                'A': 'XX',
                'B': b_val,
                'C': c_val
            })

# 4. 合并相邻且B、C相同的区间
c_result = pd.DataFrame(result).sort_values(by=['From', 'B', 'C']).reset_index(drop=True)
merged_intervals = []
if not c_result.empty:
    current = c_result.iloc[0].to_dict()
    for idx in range(1, len(c_result)):
        row = c_result.iloc[idx].to_dict()
        # 若当前区间的结束等于下一个区间的开始,且B、C相同,则合并
        if current['To'] == row['From'] and current['B'] == row['B'] and current['C'] == row['C']:
            current['To'] = row['To']
        else:
            merged_intervals.append(current)
            current = row
    merged_intervals.append(current)

# 格式化日期并生成最终结果
c_final = pd.DataFrame(merged_intervals)
c_final['From'] = c_final['From'].apply(format_date)
c_final['To'] = c_final['To'].apply(format_date)

print(c_final)

运行结果

From         To   A    B    C
0    1-1-2024  15-1-2024  XX   YY   LL
1   16-1-2024   1-1-9999  XX   YY   OO
2    2-2-2024   1-1-9999  XX   ZZ   OO

内容的提问来源于stack exchange,提问作者user23495865

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 21:28:09