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

多条件对比两个DataFrame,移除符合对应ID日期范围的行

Pandas: Remove Rows Where ID Exists in Another DataFrame and Date Falls in Date Range

先明确我们的数据源(修正了原始数据的排版,区分行号与数据列):

原始DataFrames

df-a

IDStart_DateEnd_Date
cd22020-06-012020-06-09
cd22020-06-242020-07-21
cd562020-06-102020-07-03
cd9152020-04-282020-07-21
cd1032020-04-132020-04-24

df-b

IDDate
cd22020-05-12
cd22020-04-12
cd22020-06-29
cd152020-04-28
cd1932020-04-13

需求

移除df-b中满足以下条件的行:

  • 该行的ID在df-a中存在
  • 该行的Date落在df-a中对应ID的任意一个[Start_Date, End_Date]区间内

解决方案

用Pandas的合并+分组操作实现,高效且逻辑清晰:

首先构造并格式化DataFrames(确保日期列是datetime类型,这是日期判断的前提):

import pandas as pd

# 构造df-a
df_a = pd.DataFrame({
    'ID': ['cd2', 'cd2', 'cd56', 'cd915', 'cd103'],
    'Start_Date': pd.to_datetime(['2020-06-01', '2020-06-24', '2020-06-10', '2020-04-28', '2020-04-13']),
    'End_Date': pd.to_datetime(['2020-06-09', '2020-07-21', '2020-07-03', '2020-07-21', '2020-04-24'])
})

# 构造df-b
df_b = pd.DataFrame({
    'ID': ['cd2', 'cd2', 'cd2', 'cd15', 'cd193'],
    'Date': pd.to_datetime(['2020-05-12', '2020-04-12', '2020-06-29', '2020-04-28', '2020-04-13'])
})

然后执行核心过滤逻辑:

# 按ID左连接两个DataFrame,保留df-b的所有行
merged = df_b.merge(df_a, on='ID', how='left')

# 判断每行的Date是否落在对应的Start_Date和End_Date之间
in_range = (merged['Date'] >= merged['Start_Date']) & (merged['Date'] <= merged['End_Date'])

# 对df-b的原始行分组,检查是否存在任意一个匹配区间包含Date
to_remove = merged.groupby(merged.index)['in_range'].any()

# 保留不需要移除的行
result = df_b[~to_remove]

# 输出结果
print(result)

输出结果

ID       Date
0    cd2 2020-05-12
1    cd2 2020-04-12
3   cd15 2020-04-28
4  cd193 2020-04-13

逻辑说明

  1. 左连接:确保df-b的所有行都被保留,ID不在df-a中的行,其Start/End_Date会是NaN,后续判断自动排除这类行的移除可能。
  2. 区间判断:对每个合并后的行,生成布尔值标记Date是否在对应区间内。
  3. 分组检查:按df-b原始行索引分组,只要该行有任意一个匹配区间满足条件,就标记为需要移除。
  4. 过滤结果:用~to_remove取反,保留不符合移除条件的行。

这个方法避免了逐行循环,处理大规模数据集时效率更高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 22:17:52