合并两个熊猫数据框,同时进行过滤和聚合

时间:2019-06-04 10:41:55

标签: python pandas pandas-groupby

我有两个熊猫数据框。一种格式如下:

|Customer ID | Login_Session_Start_Time | Login_Session_End_Time | 
|------------|--------------------------|------------------------|
|   1        | 2018-04-05 10:03:23      |  2018-04-05 10:15:12   |
|   1        | 2018-04-19 22:12:42      |  2018-04-19 22:45:11   | 
|   2        | 2018-04-01 08:23:14      |  2018-04-01 14:34:01   |
........

列出每个客户在某个网站上花费的时间。我还有另一个来自不同来源的数据框,其中列出了他们购买的商品和时间。看起来像这样:

| Customer ID |  Purchase Description    | Purchase Time        |
|-------------|--------------------------|----------------------|
|     1       | Shirt                    | 2018-04-05 10:11:04  |
|     2       | Pants                    | 2018-04-01 09:35:13  |
|     2       | Shirt                    | 2018-04-01 13:12:09  |

.........

我需要以这样的方式合并两个数据框,以告诉我客户在每个登录会话中购买了多少种商品。因此,对于上面的示例,它看起来像:

|Customer ID | Login_Session_Start_Time | Login_Session_End_Time | Num_Shirts | Num_Pants |
|------------|--------------------------|------------------------|------------|-----------|
|   1        | 2018-04-05 10:03:23      |  2018-04-05 10:15:12   |   1        |        0  |
|   2        | 2018-04-01 08:23:14      |  2018-04-01 14:34:01   |   1        |        1  |
 .....

因此,这将涉及过滤时的合并(在“购买时间”在Login_Session_Start_Time和Login_Session_End_Time范围内),分组(按“购买描述”)以及可能进行透视。

我想到的唯一方法是循环遍历第一个数据框的每一行,然后在循环中选择第二个数据框的子数据框,该子数据框具有匹配的客户ID,并且购买时间在第一行,然后分组并旋转该子数据帧,然后将所有这些子数据帧组装在一起成为最后一个。它可以工作,但是非常慢,尤其是对于具有成千上万行的数据帧。

有更好的方法吗?谢谢您的帮助!

2 个答案:

答案 0 :(得分:1)

尝试将两个pd.DataFrame.groupbypd.DataFrame.joinpd.get_dummies一起使用:

print(df.groupby('Customer ID', as_index=False).first().join(pd.get_dummies(df2, columns=['Purchase Description']).groupby(['Customer ID'], as_index=False).sum().iloc[:, 1:]))

输出:

   Customer ID Login_Session_Start_Time Login_Session_End_Time  \
0            1        20180405 10:03:23      20180405 10:15:12   
1            2        20180401 08:23:14      20180401 14:34:01   

   Purchase Description_Pants  Purchase Description_Shirt  
0                           0                           1  
1                           1                           1

答案 1 :(得分:0)

如果要在会话中购买,我想合并并series.between()进行比较:

m=df1.merge(df2,on='Customer ID')
m=m[m['Purchase Time'].between(m['Login_Session_Start_Time'],m['Login_Session_End_Time'])]
m=(pd.get_dummies(m.drop('Purchase Time',1),columns=['Purchase Description'],
                                                     prefix='',prefix_sep=''))

Customer ID Login_Session_Start_Time    Login_Session_End_Time  Pants   Shirt
0   1       2018-04-05 10:03:23         2018-04-05 10:15:12         0       1
2   2       2018-04-01 08:23:14         2018-04-01 14:34:01         1       0
3   2       2018-04-01 08:23:14         2018-04-01 14:34:01         0       1