如何按Person分组删除available_df中被delete_df时间区间包含的行?
解决思路与代码实现
首先假设你的两个DataFrame结构如下(需确保时间列是datetime类型):
import pandas as pd # 示例数据 available_df = pd.DataFrame({ 'Person': ['Alice', 'Alice', 'Bob', 'Charlie'], 'start_time': pd.to_datetime(['2024-01-01', '2024-01-10', '2024-02-01', '2024-03-01']), 'end_time': pd.to_datetime(['2024-01-05', '2024-01-15', '2024-02-10', '2024-03-10']) }) delete_df = pd.DataFrame({ 'Person': ['Alice', 'Bob'], 'start_time': pd.to_datetime(['2024-01-08', '2024-02-05']), 'end_time': pd.to_datetime(['2024-01-20', '2024-02-15']) })
步骤1:统一时间格式(必做)
先把两个DataFrame的时间列转为datetime类型,避免字符串比较出错:
available_df[['start_time', 'end_time']] = available_df[['start_time', 'end_time']].apply(pd.to_datetime) delete_df[['start_time', 'end_time']] = delete_df[['start_time', 'end_time']].apply(pd.to_datetime)
步骤2:按Person关联两个DataFrame
用merge按Person做笛卡尔积,让每个available的行都能匹配到同Person的所有待删除时间区间:
merged = available_df.merge(delete_df, on='Person', suffixes=('_avail', '_del'), how='left')
步骤3:标记需要删除的行
判断available的时间区间是否被delete的区间完全包含,只要有一个匹配的delete区间满足条件,就标记为待删除;没有对应Person的行默认不删除:
merged['to_delete'] = ( (merged['start_time_avail'] >= merged['start_time_del']) & (merged['end_time_avail'] <= merged['end_time_del']) ).fillna(False)
步骤4:过滤得到结果
按available的原始行分组,只要该组内有一个to_delete为True,就删除该行:
result = available_df[~merged.groupby(available_df.index)['to_delete'].any()]
运行后,示例中Alice的第二行(2024-01-10至2024-01-15)会被删除,因为被delete_df的区间包含;其他行保留。
补充说明
- 如果delete_df中同一个Person有多个时间区间,上述逻辑会检查所有区间,只要被其中一个包含就删除。
- 若你的时间列命名不同,替换代码中对应的列名即可。
内容的提问来源于stack exchange,提问作者ymmy
相关产品推荐
相关产品推荐

