Pandas 带条件分组的 groupBy

Pandas groupBy with conditional grouping

我有两个数据框,需要根据第二个 df 的某些标准对第一个进行分组。

df1= 
     summary  participant_id response_date
0        2.0              11    2016-04-30
1        3.0              11    2016-05-01
2        3.0              11    2016-05-02
3        3.0              11    2016-05-03
4        3.0              11    2016-05-04
5        3.0              11    2016-05-05
6        3.0              11    2016-05-06
7        4.0              11    2016-05-07
8        4.0              11    2016-05-08
9        3.0              11    2016-05-09
10       3.0              11    2016-05-10
11       3.0              11    2016-05-11
12       3.0              11    2016-05-12
13       3.0              11    2016-05-13
14       3.0              11    2016-05-14
15       3.0              11    2016-05-15
16       3.0              11    2016-05-16
17       4.0              11    2016-05-17
18       3.0              11    2016-05-18
19       3.0              11    2016-05-19
20       3.0              11    2016-05-20
21       4.0              11    2016-05-21
22       4.0              11    2016-05-22
23       4.0              11    2016-05-23
24       3.0              11    2016-05-24
25       3.0              11    2016-05-25
26       3.0              11    2016-05-26
27       3.0              11    2016-05-27
28       3.0              11    2016-05-28
29       3.0              11    2016-05-29
..       ...             ...           ... 

df2 =
    summary  participant_id response_date
0      12.0              11    2016-04-30
1      12.0              11    2016-05-14
2      14.0              11    2016-05-28
.       ...             ...           ...     

我需要在 df2 列中的日期之间对 df1 进行分组(获取块)。即:

df1= 
         summary  participant_id response_date
             2.0              11    2016-04-30

             3.0              11    2016-05-01
             3.0              11    2016-05-02
             3.0              11    2016-05-03
             3.0              11    2016-05-04
             3.0              11    2016-05-05
             3.0              11    2016-05-06
             4.0              11    2016-05-07
             4.0              11    2016-05-08
             3.0              11    2016-05-09
             3.0              11    2016-05-10
             3.0              11    2016-05-11
             3.0              11    2016-05-12
             3.0              11    2016-05-13
             3.0              11    2016-05-14

             3.0              11    2016-05-15
             3.0              11    2016-05-16
             4.0              11    2016-05-17
             3.0              11    2016-05-18
             3.0              11    2016-05-19
             3.0              11    2016-05-20
             4.0              11    2016-05-21
             4.0              11    2016-05-22
             4.0              11    2016-05-23
             3.0              11    2016-05-24
             3.0              11    2016-05-25
             3.0              11    2016-05-26
             3.0              11    2016-05-27
             3.0              11    2016-05-28

             3.0              11    2016-05-29
    ..       ...             ...           ... 

groupby的优雅解决方案吗?

可能有更优雅的解决方案,但您可以遍历 df2 中的 response_date 值,并通过检查所有 response_date 中的值来创建布尔值系列df1 简单总结一下。

df1['group'] = 0
for rd in df2.response_date.values:
    df1['group'] += df1.response_date > rd

输出:

   summary  participant_id response_date  group
0      2.0              11    2016-04-30      0
1      3.0              11    2016-05-01      1
2      3.0              11    2016-05-02      1
3      3.0              11    2016-05-03      1
4      3.0              11    2016-05-04      1

基于@Scott 的回答:

您可以使用 pd.cut,但您需要在 df2

中的 response_date 中的最早日期之前和最晚日期之后添加一个日期
dates = [pd.Timestamp('2000-1-1')] + 
         df2.response_date.sort_values().tolist() + 
        [pd.Timestamp('2020-1-1')]
df1['group'] = pd.cut(df1['response_date'], dates)

您想要 .cut method。这使您可以按其他日期列表对日期进行分类。

df1['cuts'] = pd.cut(df1['response_date'], df2['response_date'])
grouped = df1.groupby('cuts')
print grouped.max()  #for example