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

Pandas DataFrame关联需求:按ID筛选过去一年范围内的book_date数据

解决Pandas DataFrame按ID关联并筛选日期区间的问题

嘿,我来帮你搞定这个需求!我们的目标是针对df1里的每个ID,找出df2中所有落在对应ID记录日期过去一年到该日期区间内的book_date。下面分步骤给你演示实现方法:

第一步:确保日期列是datetime类型

首先得把两个DataFrame里的日期列转换成Pandas的datetime格式,这样才能正确做时间运算:

import pandas as pd

# 先模拟示例数据(你可以替换成自己的真实数据)
df1 = pd.DataFrame({
    'ID': [1, 2],
    'record_date': ['2015-02-01', '2016-05-15']
})
df2 = pd.DataFrame({
    'ID': [1, 1, 2, 2],
    'book_date': ['2015-02-01', '2014-08-03', '2016-03-20', '2015-01-10']
})

# 转换日期列
df1['record_date'] = pd.to_datetime(df1['record_date'])
df2['book_date'] = pd.to_datetime(df2['book_date'])

方法一:全量合并后过滤(适合小数据集)

这种方法逻辑直观,先按ID把两个DataFrame合并,再筛选符合日期条件的记录:

# 按ID合并两个DataFrame,保留df1的所有记录
merged_df = pd.merge(df1, df2, on='ID', how='left')

# 计算每个record_date对应的"过去一年"日期
merged_df['one_year_ago'] = merged_df['record_date'] - pd.DateOffset(years=1)

# 筛选book_date在[one_year_ago, record_date]区间内的记录
filtered_df = merged_df[
    (merged_df['book_date'] >= merged_df['one_year_ago']) & 
    (merged_df['book_date'] <= merged_df['record_date'])
]

# 提取需要的列(按需调整)
result = filtered_df[['ID', 'record_date', 'book_date']]

运行后,针对你举的ID=1的例子:record_date是2015-02-01,one_year_ago是2014-02-01,所以2015-02-01和2014-08-03都会被保留。如果你的需求是只保留等于record_date的book_date,可以把过滤条件改成merged_df['book_date'] == merged_df['record_date']。

方法二:分组处理(适合大数据集)

如果你的数据量很大,全量合并会占用过多内存,用groupby+apply的方式更高效:

def filter_book_dates(group):
    # 获取当前分组的record_date(每个ID在df1里应该只有一条记录吧?如果有多条需要调整)
    record_date = group['record_date'].iloc[0]
    one_year_ago = record_date - pd.DateOffset(years=1)
    # 从df2中筛选同ID且日期符合条件的记录
    valid_books = df2[
        (df2['ID'] == group.name) & 
        (df2['book_date'] >= one_year_ago) & 
        (df2['book_date'] <= record_date)
    ]
    # 把record_date补到结果里
    valid_books['record_date'] = record_date
    return valid_books

# 按ID分组处理df1
result = df1.groupby('ID').apply(filter_book_dates).reset_index(drop=True)

这种方法只会对每个ID的记录进行关联和筛选,避免了全量合并的内存开销。

验证结果

对于我们的示例数据,最终的result会是:

IDrecord_datebook_date
12015-02-012015-02-01
12015-02-012014-08-03
22016-05-152016-03-20

如果你的实际需求是排除2014-08-03,那可能是对“过去一年”的定义有差异,比如你想筛选最近30天或者仅等于record_date的记录,只需要修改过滤条件里的时间差即可(比如把pd.DateOffset(years=1)改成pd.DateOffset(days=30))。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 08:01:05