【问题标题】:How to merge two datasets based on conditions如何根据条件合并两个数据集
【发布时间】:2020-10-13 14:19:23
【问题描述】:

我正在尝试根据 3 个条件在 python 中合并两个数据集。它们必须具有相同的经度、纬度和特定年份的月份。一个数据集的大小约为 16k,另一个为 1.7k。 输入和预期输出的简单示例如下:

>df1
 long  lat  date        proximity
 5      8   23/06/2009    Near
 6      10  05/10/2012    Far
 8      6   19/02/2010    Near
 3      4   30/04/2014    Near
 5      8   01/06/2009    Far

 >df2
 long  lat  date          mine
 5      8   10/06/2009     1
 8      6   24/02/2010     0
 7      2   19/04/2014     1 
 3      4   30/04/2013     1

如果任何条件为假,则合并时“我的”中的值为 0。我将如何合并得到:

 long  lat  date        proximity  mine
 5      8   23/06/2009    Near      1
 6      10  05/10/2012    Far       0
 8      6   19/02/2010    Near      0
 3      4   30/04/2014    Near      0
 5      8   01/06/2009    Far       1

如果这样更容易的话,输出中不需要日期列。

【问题讨论】:

    标签: python pandas dataframe dataset


    【解决方案1】:

    给你:

    df1['year-month'] = pd.to_datetime(df1['date'], format='%d/%m/%Y').dt.strftime('%Y/%m')
    df2['year-month'] = pd.to_datetime(df2['date'], format='%d/%m/%Y').dt.strftime('%Y/%m')
    
    joined = df1.merge(df2,
              how='left',
              on =['long', 'lat', 'year-month'],
              suffixes=['', '_r']).drop(columns = ['date_r', 'year-month'])
    joined['mine'] = joined['mine'].fillna(0).astype(int)
    print(joined)
    

    输出

       long  lat        date proximity  mine
    0     5    8  23/06/2009      Near     1
    1     6   10  05/10/2012       Far     0
    2     8    6  19/02/2010      Near     0
    3     3    4  30/04/2014      Near     0
    4     5    8  01/06/2009       Far     1
    

    【讨论】:

    • 抱歉我不够具体,月份必须在特定年份(所以月份/年份必须匹配),上面的代码只考虑任何年份的月份。我将编辑问题以在 df2 中显示另一行以便更好地理解。
    • @Celeye 好吧。已更新。
    【解决方案2】:

    首先从date列中提取monthyear并将其分配给临时列mon-year,然后使用DataFrame.merge左合并数据框df1df2long, lat and mon-year上,然后使用Series.fillnamine 列中的NaN 值填充为0,最后使用DataFrame.drop 删除临时列mon-year

    df1['mon-year'] = df1['date'].str.extract(r'/(.*)')
    df2['mon-year'] = df2['date'].str.extract(r'/(.*)')
    
    # OR we can use pd.to_datetime,
    # df1['mon-year'] = pd.to_datetime(df1['date'], format='%d/%m/%Y').dt.strftime('%m-%Y')
    # df2['mon-year'] = pd.to_datetime(df2['date'], format='%d/%m/%Y').dt.strftime('%m-%Y')
    
    df3 = df1.merge(
        df2.drop('date', 1),
        on=['long', 'lat', 'mon-year'], how='left').drop('mon-year', 1)
    
    df3['mine'] = df3['mine'].fillna(0)
    

    结果:

    # print(df3)
    
       long  lat        date proximity  mine
    0     5    8  23/06/2009      Near   1.0
    1     6   10  05/10/2012       Far   0.0
    2     8    6  19/02/2010      Near   0.0
    3     3    4  30/04/2014      Near   0.0
    4     5    8  01/06/2009       Far   1.0
    

    【讨论】:

    • 抱歉,月份必须在特定年份(因此月份/年份必须匹配),上面的代码只考虑任何年份的月份。当我运行上面的代码时,我还获得了超过 10k 的额外积分作为重复项?我将编辑问题
    • @Celeye 没关系。编辑了答案。
    【解决方案3】:

    您可以使用多个键进行合并,如下所示:

    df_1.merge(df_2, how='left', left_on=['long', 'lat', 'date'], right_on=['long', 'lat', 'date'])
    

    【讨论】:

      猜你喜欢
      • 2020-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-13
      • 2020-07-24
      相关资源
      最近更新 更多