【问题标题】:Left join two dateframes with date columns on a range of dates?左连接两个数据框,其中包含日期范围内的日期列?
【发布时间】:2022-02-10 14:38:03
【问题描述】:

这是一个满足条件的示例。数据框 df1 和 df2 都有 id 列和 date 列。在 df1 中,id 列是唯一的,而在 df2 中,它是非唯一的。我想创建一个新的数据框,如果 df1.id == df2.id 并且 df2 中的某些日期对在 df1 中的日期的 1 周内,则发生连接

df1

| customer_id (unique) | 'purchase_date'|
| --------             | -------------- |
| 1                    | 2021-05-14     |
| 2                    | 2021-09-16     |

df2

| customer_id | 'visit_dates'  |
| --------    | -------------- |
| 1           | 2021-05-11     |
| 1           | 2021-05-16     |
| 1           | 2021-05-21     |
| 2           | 2021-07-14     |
| 2           | 2021-09-17     |


# New Df will only have 1 row.
# For customer 1 there is a date within the range(05-07 -> 05-14) 
# and within the range(05-14 -> 05-21) with matching id. 
# For customer 2, there are no dates within (09-09 -> 09-16) so it should be filtered

newdf

| customer_id (unique) | 'purchase_date'| begin_date_range | end_date_range
| --------             | -------------- | ---------------- | -------------
| 1                    | 2021-05-14     | 2021-05-11       | 2021-05-16

我了解如何在 SQL 中执行此操作,但我不知道哪些函数允许在 Pandas 中进行类似的日期谓词过滤。

构造df1df2

data1 = {'customer_id': [1, 2], 'purchase_date': ['2021-05-14', '2021-09-16']}

data2 = {'customer_id': [1, 1, 1, 2, 2],
         'visit_dates': ['2021-05-11', '2021-05-16', '2021-05-21', '2021-07-14', '2021-09-17']}

【问题讨论】:

  • 你能添加一些我们可以运行的df = pd.DataFrame({...}) 语句来创建DataFrame吗?

标签: python pandas dataframe date


【解决方案1】:

以@Raymond Kwok 的出色回答为基础:我们可以merge 两次,一次向左合并df1df2,然后将“begin_date_range”部分与“end_date_range”部分合并

merged = df1.merge(df2, on='customer_id', how='left')
merged['purchase_date'] = pd.to_datetime(merged['purchase_date'])
merged['visit_dates'] = pd.to_datetime(merged['visit_dates'])

day_diff = merged['purchase_date'].sub(merged['visit_dates']).dt.days
out = (merged[day_diff.between(0,6)]
       .merge(merged[day_diff.between(-6,0)], on=['customer_id','purchase_date'])
       .rename(columns={'visit_dates_x': 'begin_date_range', 'visit_dates_y': 'end_date_range'}))

输出:

   customer_id purchase_date begin_date_range end_date_range
0            1    2021-05-14       2021-05-11     2021-05-16

【讨论】:

    【解决方案2】:

    使用周条件过滤merge 结果。

    df = df1.merge(df2, on='customer_id', how='left')
    df[(df['purchase_date'] - df['visit_dates']).dt.days.between(0, 6)]
    df['visit_dates+1week'] = df['visit_dates'] + pd.Timedelta(days=6)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-11-02
      • 1970-01-01
      • 1970-01-01
      • 2020-01-07
      • 2018-12-19
      • 2020-04-30
      • 1970-01-01
      相关资源
      最近更新 更多