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

如何用Python合并含重叠数据且有特殊规则的两个DataFrame

基于规则的DataFrame合并实现方案

核心逻辑梳理

  • 按ID分组处理,确保区间判断仅在同一ID范围内生效
  • 识别连续20英尺(即4个连续5英尺子区间)且所有df1数值列全为-99的片段
  • 仅对符合条件的片段用df2数据覆盖df1,其余场景完全保留df1数据
  • 自动处理列差异:保留两个DataFrame的所有列,df1列优先,df2补充df1缺失的列

代码实现

1. 导入依赖与加载数据(示例)

import pandas as pd
import numpy as np

# 替换为你实际的数据加载代码
df1 = pd.DataFrame({
    'ID': ['A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'B', 'B'],
    'depth': [410, 415, 420, 425, 430, 435, 440, 445, 500, 505],
    'value1': [10, -99, -99, -99, -99, 20, -99, 30, -99, -99],
    'value2': [5, 6, -99, -99, -99, -99, 7, 8, 15, 16]
})

df2 = pd.DataFrame({
    'ID': ['A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'B', 'B'],
    'depth': [410, 415, 420, 425, 430, 435, 440, 445, 500, 505],
    'value1': [11, 12, 13, 14, 15, 21, 22, 31, 100, 101],
    'value2': [6, 7, 8, 9, 10, 11, 8, 9, 16, 17],
    'value3': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
})

2. 对齐行与标记需覆盖区间

# 按ID和depth对齐两个DataFrame,保留所有行
merged = pd.merge(df1, df2, on=['ID', 'depth'], how='outer', suffixes=('_df1', '_df2'))
merged = merged.sort_values(['ID', 'depth']).reset_index(drop=True)

def mark_coverage_groups(group):
    # 标记当前行所有df1数值列是否全为-99
    df1_num_cols = [col for col in merged.columns if col.endswith('_df1')]
    group['all_missing'] = group[df1_num_cols].apply(lambda row: all(val == -99 for val in row), axis=1)
    
    # 对连续缺失行分组
    group['missing_group'] = (group['all_missing'] != group['all_missing'].shift()).cumsum()
    
    # 筛选出长度为20英尺的连续缺失分组
    group_stats = group.groupby('missing_group').agg(
        depth_range=('depth', lambda x: x.max() - x.min()),
        is_missing=('all_missing', 'first')
    ).reset_index()
    valid_groups = group_stats[(group_stats['is_missing']) & (group_stats['depth_range'] == 20)]
    
    # 标记需要覆盖的行
    group['need_cover'] = group['missing_group'].isin(valid_groups['missing_group'])
    return group

# 按ID分组执行标记逻辑
merged = merged.groupby('ID').apply(mark_coverage_groups).reset_index(drop=True)

3. 执行覆盖与合并最终列

# 提取所有唯一列名(去除后缀)
all_raw_cols = set(col.replace('_df1', '').replace('_df2', '') for col in merged.columns if '_df1' in col or '_df2' in col)

final_df = pd.DataFrame()
final_df[['ID', 'depth']] = merged[['ID', 'depth']]

# 逐列合并:优先df1,符合条件时用df2覆盖,df1无的列直接取df2
for col in all_raw_cols:
    df1_col = f"{col}_df1"
    df2_col = f"{col}_df2"
    
    if df1_col in merged.columns:
        final_df[col] = np.where(merged['need_cover'], merged[df2_col], merged[df1_col])
    else:
        final_df[col] = merged[df2_col]

# 填充可能的空值(按需调整,比如替换为-99)
final_df = final_df.fillna(-99)

4. 查看结果

print(final_df)

关键细节说明

  • 多数值列兼容:自动识别所有df1的数值列,仅当整行所有数值列全为-99时,才判定为缺失行
  • 区间精度:通过计算连续缺失分组的深度差判断是否为20英尺,适配5英尺间隔的子区间规则
  • 列差异处理:无需提前指定列名,自动合并两个DataFrame的所有列,保证df1数据优先级

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 09:06:37