如何基于另一个DataFrame的条件筛选DataFrame行
高效筛选DataFrame行的解决方案
问题背景
现有两个DataFrame:
df1:
Date Fruit 2022-11-24 Banana 2021-5-23 Orange 2020-10-1 Apple
df2:
Start_Date End_Date Fruit 2021-11-20 2022-12-31 Banana 2022-6-1 2022-10-31 Banana 2013-14-1 2022-11-31 Banana 2013-11-24 2022-10-31 Celery 2013-11-25 2022-10-31 Apple 2013-11-25 2022-10-31 Orange
需要生成df3,包含df2中满足以下条件的行:
- 与df1中某一行的Fruit值相同,且df1的Date落在df2的Start_Date和End_Date区间内
预期结果df3:
Start_Date End_Date Fruit 2021-11-20 2022-12-31 Banana 2013-14-01 2022-11-31 Banana 2013-11-25 2022-10-31 Apple 2013-11-25 2022-10-31 Orange
原代码通过循环遍历df1行筛选,处理大型数据集时效率极低:
df3 = pd.DataFrame() for _, row in df1.iterrows(): FRUIT= row['FRUIT'] DATE= row['DATE'] temp= df2[(df2['FRUIT'] == FRUIT) &(df2['Start_Date'] <= DATE) &(df2['End_Date'] >= DATE)] df3 = pd.concat([df3 , temp])
高效解决方案
使用向量化的合并与筛选操作替代循环,大幅提升效率:
import pandas as pd # 1. 转换所有日期列为datetime类型(确保日期比较准确) df1['Date'] = pd.to_datetime(df1['Date'], errors='coerce') df2['Start_Date'] = pd.to_datetime(df2['Start_Date'], errors='coerce') df2['End_Date'] = pd.to_datetime(df2['End_Date'], errors='coerce') # 2. 按Fruit列合并两个DataFrame,只保留共同Fruit的行 merged_df = df2.merge(df1, on='Fruit', how='inner') # 3. 筛选满足日期区间条件的行 filtered_df = merged_df[(merged_df['Start_Date'] <= merged_df['Date']) & (merged_df['Date'] <= merged_df['End_Date'])] # 4. 提取df2的原始列并去重(避免同一df2行被多次匹配) df3 = filtered_df[['Start_Date', 'End_Date', 'Fruit']].drop_duplicates() # 可选:重置索引 df3 = df3.reset_index(drop=True)
方案说明
- 向量化操作(merge、布尔筛选)基于Pandas底层C实现,比Python循环快几个数量级,适合大型数据集
- 转换日期类型是关键,避免字符串格式导致的错误比较
drop_duplicates()确保df2中符合条件的行仅保留一次,即使匹配到多个df1的日期行
内容的提问来源于stack exchange,提问作者Izlan
相关产品推荐
相关产品推荐

