【问题标题】:How to join two pandas dataframes based on a date in df1 being >= date in df2如何根据df1中的日期> = df2中的日期加入两个熊猫数据框
【发布时间】:2021-04-26 20:02:39
【问题描述】:

我有一个包含关键 ID、状态、开始日期和其他特征的大型数据框。我有另一个数据框,其中包含状态、开始日期和表示标志的“1”。

我想加入两者,基于状态和 df1 中的日期大于或等于 df2 中的日期。

以下面的例子为例。 df1 是状态表、开始日期和 1 表示标志。 df2 是一个需要这些标志的数据框 if df2 中的日期是 >= df1 中的日期。最终结果是df3。唯一观察得到状态匹配且日期为 >= 原始日期的标志。

import pandas as pd

dict1 = {'date':['2020-01-01', '2020-02-15', '2020-02-04','2020-03-17',
                 '2020-06-15'],
         'state':['AL','FL','MD','NC','SC'],
         'flag': [1,1,1,1,1]}
df1 = pd.DataFrame(dict1)
df1['date'] = pd.to_datetime(df1['date'])

dict2 = {'state': ['AL','FL','MD','NC','SC'],
         'keyid': ['001','002','003','004','005'],
         'start_date':['2020-02-01', '2020-01-15', '2020-01-30','2020-05-18',
                       '2020-05-16']}
df2 = pd.DataFrame(dict2)
df2['start_date'] = pd.to_datetime(df2['start_date'])

df3 = df2
df3['flag'] = [0,1,1,0,1]

如何以编程方式访问 df3?我实际的df1 每个州都有一行。我实际的df2 有超过一百万个不同日期的观察结果。

【问题讨论】:

    标签: python pandas join


    【解决方案1】:

    使用df.mergenumpy.where

    In [29]: import numpy as np
    
    In [30]: df3 = df2.merge(df1)[['state', 'keyid', 'start_date', 'date']]
    
    In [31]: df3['flag'] = np.where(df3['start_date'].ge(df3['date']), 0, 1)
    
    In [33]: df3.drop('date', 1, inplace=True)
    
    In [34]: df3
    Out[34]: 
      state keyid start_date  flag
    0    AL   001 2020-02-01     0
    1    FL   002 2020-01-15     1
    2    MD   003 2020-01-30     1
    3    NC   004 2020-05-18     0
    4    SC   005 2020-05-16     1
    

    【讨论】:

      【解决方案2】:

      使用merge_asof 通过参数direction='forward' 以更大或相等的日期时间进行合并:

      “向前”搜索选择右侧 DataFrame 中“on”键大于或等于左侧键的第一行。

      df2['need'] = [0,1,1,0,1]
      
      df1 = df1.sort_values('date')
      df2 = df2.sort_values('start_date')
      
      df = pd.merge_asof(df2, 
                         df1, 
                         left_on='start_date', 
                         right_on='date', 
                         by='state',
                         direction='forward')
      
      
      df['flag'] = df['flag'].fillna(0).astype(int)
      print (df)
      
        state keyid start_date  need       date  flag
      0    FL   002 2020-01-15     1 2020-02-15     1
      1    MD   003 2020-01-30     1 2020-02-04     1
      2    AL   001 2020-02-01     0        NaT     0
      3    SC   005 2020-05-16     1 2020-06-15     1
      4    NC   004 2020-05-18     0        NaT     0
      

      您也可以rename 列以避免在输出中追加DataFrame

      df2['need'] = [0,1,1,0,1]
      
      df1 = df1.sort_values('date')
      df2 = df2.sort_values('start_date')
      
      df = pd.merge_asof(df2, 
                         df1.rename(columns={'date':'start_date'}), 
                         on='start_date', 
                         by='state',
                         direction='forward')
      
      df['flag'] = df['flag'].fillna(0).astype(int)
      print (df)
        state keyid start_date  need  flag
      0    FL   002 2020-01-15     1     1
      1    MD   003 2020-01-30     1     1
      2    AL   001 2020-02-01     0     0
      3    SC   005 2020-05-16     1     1
      4    NC   004 2020-05-18     0     0
      

      【讨论】:

        猜你喜欢
        • 2018-10-28
        • 1970-01-01
        • 2019-08-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-05-05
        • 2013-06-09
        相关资源
        最近更新 更多