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
软件包的作者。
对于某些项目,我正在尝试从 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
:
>>> 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
软件包的作者。