如何将具有多个条件的DataFrame连接到不同的列?

时间:2018-12-26 14:04:39

标签: python pandas dataframe join merge

我有两个数据帧,如下所示: mydata1:

   ID   X1   X2  Date1
   002  324  634  2016-01-01
   002  334  534  2016-01-14 
   002  354  834  2016-01-30
   004  543  843  2017-02-01
   004  923  043  2017-04-15
   005  032  212  2015-09-01 
   005  523  843  2017-09-15
   005  212  222  2015-10-1

mydata2:

   ID   Y1     Y2    Date2
   002  1224   234  2016-01-04
   002  1254   249  2016-01-28
   004  321    212  2016-12-01 
   005  1121   222  2017-09-13 

我想基于ID和Date合并这两个数据帧,其中Date1 --dataframe1--和Date2 --indataframe2-之间的差异小于15。所以,我想要的数据帧作为输出应该是这样的:

    ID   X1   X2    Date1.      Y1.  Y2.      Date2
   002  324  634  2016-01-01.   nan.  nan.     nan
   002  334  534  2016-01-14    1224  234   2016-01-04
   002  354  834  2016-01-30.   1254   249  2016-01-28
   004  543  843  2017-02-01    321   212   2015-12-01 
   004  923  043  2017-04-15.    nan   nan.   nan
   005  032  212  2015-09-01    nan   nan.   nan
   005  523  843  2015-09-15.   1121  222   2017-09-13
   005  212  222  2015-10-1.    nan   nan.   nan

1 个答案:

答案 0 :(得分:0)

所以您期望的输出略有错误,因为其中一个值比合并值大了2年。

首先我们执行联接:

f = df.merge(df1, how='left', on='ID')

   ID   X1   X2       Date1    Y1   Y2       Date2
0   2  324  634  2016-01-01  1224  234  2016-01-04
1   2  334  534  2016-01-14  1224  234  2016-01-04
2   2  354  834  2016-01-30  1224  234  2016-01-04
3   4  543  843  2017-02-01   321  212  2016-12-01
4   4  923   43  2017-04-15   321  212  2016-12-01
5   5   32  212  2015-09-01  1121  222  2015-09-13
6   5  523  843  2015-09-15  1121  222  2015-09-13
7   5  212  222   2015-10-1  1121  222  2015-09-13

然后我们创建一个布尔掩码:

mask = (pd.to_datetime(f['Date1'], format='%Y-%m-%d') - pd.to_datetime(f['Date2'], format='%Y-%m-%d')).apply(lambda i: i.days <= 15 and i.days > 0)

0    False
1     True
2    False
3    False
4    False
5    False
6     True
7    False

然后我们将其设置为条件不匹配的nan

f.loc[~mask, ['Y1', 'Y2', 'Date2']] = np.nan

   ID   X1   X2       Date1      Y1     Y2       Date2
0   2  324  634  2016-01-01     NaN    NaN         NaN
1   2  334  534  2016-01-14  1224.0  234.0  2016-01-04
2   2  354  834  2016-01-30     NaN    NaN         NaN
3   4  543  843  2017-02-01     NaN    NaN         NaN
4   4  923   43  2017-04-15     NaN    NaN         NaN
5   5   32  212  2015-09-01     NaN    NaN         NaN
6   5  523  843  2015-09-15  1121.0  222.0  2015-09-13
7   5  212  222   2015-10-1     NaN    NaN         NaN