通过使用Pandas在Python中查找加入2 df

时间:2017-12-08 17:06:41

标签: python pandas join dataframe

我很难通过查找来执行数据框连接:

df1

Name ID1    StartDate1  EndDate1    StartDate2  EndDate2
ab   111    1/1/2017    3/1/2017    2/1/2017    4/1/2017
bc   112    2/1/2017    3/1/2017    2/1/2017    4/1/2017
cd   113    1/1/2017    2/1/2017    2/1/2017    4/1/2017
df   114    2/1/2017    4/1/2017    2/1/2017    4/1/2017
fe   115    4/1/2017    5/1/2017    2/1/2017    4/1/2017

df2

ID1 ID2 Date     Id1_num  id2_num
111 10  1/1/2017    10      11
111 10  2/1/2017            10
111 10  3/1/2017    13      13
111 10  4/1/2017    15      13
112 20  2/1/2017    11      19
112 20  3/1/2017    12  
112 20  4/1/2017            19
113 20  1/1/2017    17       5
113 20  2/1/2017    17      14
114 30  2/1/2017    11      13
114 30  3/1/2017    10  
114 30  4/1/2017    18      13
115 30  4/1/2017    7        5
115 30  5/1/2017    13      19

我想要我的结果df3

Name   ID1    ID2   StartDate1  EndDate1    StartDate2  EndDate2    ID1Date1Count   ID1Date1Average   ID1Date2Count    ID1Date2Average    ID2Date1Count    ID2Date1Average    ID2Date2Count    ID2Date2Average
ab     111    10    1/1/2017    3/1/2017    2/1/2017    4/1/2017    2               11.5              2                14                 3                11.33              3                12
bc     112    20    2/1/2017    3/1/2017    2/1/2017    4/1/2017    2               11.5              2                11.5               1                19                 2                19
cd     113    20    1/1/2017    2/1/2017    2/1/2017    4/1/2017    2               17                1                17                 1                14                 1                14
df     114    30    2/1/2017    4/1/2017    2/1/2017    4/1/2017    3               13                3                13                 2                13                 2                13
fe     115    30    4/1/2017    5/1/2017    2/1/2017    4/1/2017    1               19                0                0                  1                19                 0                0

其中 ID1Date1Count是日期间隔[StartDate1, EndDate1]的条目数, ID1Date2Count是日期间隔[StartDate2, EndDate2]中的条目数 ID2Date1Count是日期间隔[StartDate1, EndDate1]中的条目数 ID2Date2Count是日期间隔[StartDate2, EndDate2]中的条目数 随着他们的平均水平。 这里的额外条件是,如果num,我们不会包含num < 10

非常感谢!

2 个答案:

答案 0 :(得分:1)

我打破了这些步骤,在我们收到dd1之后,我们可以merge将其恢复为df1,您可以使用NaN替换fillna(0) }

Newdf=pd.wide_to_long(df1,stubnames=['StartDate','EndDate'],i=['Name','ID1'],j='nnumer')
Newdf.StartDate=pd.to_datetime(Newdf.StartDate)
Newdf.EndDate=pd.to_datetime(Newdf.EndDate)
Newdf['New']=Newdf[['StartDate','EndDate']].apply(lambda x : [pd.date_range(x['StartDate'], x['EndDate'],freq='MS').tolist()],1)['StartDate']
Newdf=Newdf.set_index(['StartDate','EndDate'],append=True).New.apply(pd.Series).stack()
Newdf=Newdf.to_frame('Date').reset_index()
df2.Date=pd.to_datetime(df2.Date)
dd=Newdf.merge(df2,on=['ID1','Date'])
dd[['Id1_num','id2_num']]=dd[['Id1_num','id2_num']].mask(dd[['Id1_num','id2_num']]<10)
dd1=dd.groupby(['ID1','nnumer','StartDate','EndDate'])['Id1_num','id2_num'].agg(['mean','count']).unstack(1).groupby(level='ID1').ffill().bfill().reset_index(['StartDate','EndDate'],drop=True).drop_duplicates()

dd1
Out[626]: 
       Id1_num                     id2_num                 
          mean       count            mean       count     
nnumer       1     2     1    2          1     2     1    2
ID1                                                        
111       11.5  14.0   2.0  2.0  11.333333  12.0   3.0  3.0
112       11.5  11.5   2.0  2.0  19.000000  19.0   1.0  2.0
113       17.0  17.0   2.0  1.0  14.000000  14.0   1.0  1.0
114       13.0  13.0   3.0  3.0  13.000000  13.0   2.0  2.0
115       13.0   NaN   1.0  0.0  19.000000   NaN   1.0  0.0

更新

dd1.columns=dd1.columns.map(''.join)
dd1
Out[650]: 
     Id1_nummean1  Id1_nummean2  Id1_numcount1  Id1_numcount2  id2_nummean1  \
ID1                                                                           
111          11.5          14.0            2.0            2.0     11.333333   
112          11.5          11.5            2.0            2.0     19.000000   
113          17.0          17.0            2.0            1.0     14.000000   
114          13.0          13.0            3.0            3.0     13.000000   
115          13.0           NaN            1.0            0.0     19.000000   
     id2_nummean2  id2_numcount1  id2_numcount2  
ID1                                              
111          12.0            3.0            3.0  
112          19.0            1.0            2.0  
113          14.0            1.0            1.0  
114          13.0            2.0            2.0  
115           NaN            1.0            0.0 

答案 1 :(得分:0)

不是100%明确你真正想要的东西(例如&#34; num&lt; 10&#34;,num?Id1_num或id2_num?),但下面的内容应该让你接近我相信。

首先 - 将df2分组并将其格式化为日期间隔:

df2_grouped = df2.groupby(['ID1', 'ID2']).\
    apply(lambda x: pd.Series([x['Date'].min(), x['Date'].max(), 
                               x['id2_num'].count()],
                              index=['StartDate2', 'EndDate2', 'ID1Date1Count']))
df2_grouped = df2_grouped.reset_index()

print(df2_grouped)

    ID1 ID2 StartDate2  EndDate2    ID1Date1Count
0   111 10  1/1/2017    4/1/2017    3
1   112 20  2/1/2017    4/1/2017    1
2   113 20  1/1/2017    2/1/2017    2
3   114 30  2/1/2017    4/1/2017    2
4   115 30  4/1/2017    5/1/2017    2

然后 - 将它与你的df1合并:

df1[['ID1', 'StartDate1', 'EndDate1']].merge(df2_grouped, on='ID1')
df1 = df1.sort_values(by=['StartDate2'])

print(df1)

    ID1 StartDate1  EndDate1    ID2 StartDate2  EndDate2    ID1Date1Count
0   111 1/1/2017    3/1/2017    10  1/1/2017    4/1/2017    3
2   113 1/1/2017    2/1/2017    20  1/1/2017    2/1/2017    2
1   112 2/1/2017    3/1/2017    20  2/1/2017    4/1/2017    1
3   114 2/1/2017    4/1/2017    30  2/1/2017    4/1/2017    2
4   115 4/1/2017    5/1/2017    30  4/1/2017    5/1/2017    2

同样,输出并不完全匹配您想要的输出,但它的关闭。