Pandas:根据第 2 列的条件对第 1 列进行分组和聚合

Pandas: Group-by and Aggregate Column 1 with Condition from Column 2

对于某些项目,我正在尝试从 R & dplyr 转移到 python 和 Pandas,我希望弄清楚如何复制我在 dplyr 中使用的常见编码策略。

一个常见的方法是,我将按特定列分组,然后计算包含来自某个第三列的条件的派生列。这是一个简单的例子:

dat = data.frame(user = rep(c("1",2,3,4),each=5),
           cancel_date = rep(c(12,5,10,11), each=5)
) %>%
  group_by(user) %>%
  mutate(login = sample(1:cancel_date[1], size = n(), replace = T)) %>%
  ungroup()

-

Source: local data frame [6 x 3]

  user cancel_date login
1    1          12     3
2    1          12     9
3    1          12    12
4    1          12     4
5    1          12     2
6    2           5     4

在此数据框中,我想计算每个用户在取消前三个月的登录次数。在 dplyr 中,这很简单:

dat %>%
  group_by(user) %>%
  summarise(logins_three_mos_before_cancel = length(login[cancel_date-login>=3]))

  user logins_three_mos_before_cancel
1    1                              4
2    2                              1
3    3                              5
4    4                              3

但我对如何做到这一点感到有点困惑 pandas。据我所知,聚合只对给定的分组列应用函数,我不知道如何让它应用涉及多个列的函数。

这是 pandas 中的相同数据:

d = { 'user' : np.repeat([1,2,3,4],5),
     'cancel_date' : np.repeat([12,5,10,11],5),
     'login' : np.array([3,  9, 12,  4,  2,  4,  3,  5,  5,  1,  3,  5,  4,  6,  3,  3,  5, 10,  7, 10])
     }
pd.DataFrame(data=d)

我希望我跟上了你的 R,但你是这个意思吗?

>> df[df.cancel_date - df.login >= 3].user.value_counts().sort_index()
1    4
2    1
3    5
4    3
dtype: int64

使用 datar:

将您的 R 代码翻译成 python 非常容易
>>> from datar.all import (
...     f, c, tibble, rep, length, set_seed,
...     group_by, mutate, sample, n, ungroup, summarise, 
... )
>>> 
>>> set_seed(8525)
>>> 
>>> dat = tibble(
...     user=rep(c("1", 2, 3, 4), each=5),
...     cancel_date=rep(c(12, 5, 10, 11), each=5)
... ) >> group_by(
...     f.user
... ) >> mutate(
...     login=sample(f[1:f.cancel_date[0]], size=n(), replace=True)
... ) >> ungroup()
>>> 
>>> dat
       user  cancel_date   login
   <object>      <int64> <int64>
0         1           12       6
1         1           12      11
2         1           12       6
3         1           12       1
4         1           12       7
5         2            5       4
6         2            5       2
7         2            5       4
8         2            5       4
9         2            5       1
10        3           10       5
11        3           10       2
12        3           10       9
13        3           10      10
14        3           10       3
15        4           11      11
16        4           11       6
17        4           11      10
18        4           11       1
19        4           11       6
>>> dat >> group_by(
...     f.user
... ) >> summarise(
...     logins_three_mos_before_cancel = length(f.login[f.cancel_date-f.login>=3])
... )
      user  logins_three_mos_before_cancel
  <object>                         <int64>
0        1                               4
1        2                               2
2        3                               3
3        4                               3

免责声明:我是 datar 软件包的作者。