pandas 的多元分组运算
Multivariate Grouped Operation with pandas
我正在尝试从 R 的 dplyr 切换到 Python 中的 pandas。我已经通过几个教程来学习基础知识,但我坚持完成一项任务。我想使用 groupby 中的 agg 方法对多个列执行操作。这是 R 中的一项微不足道的任务,如下例所示:
library(dplyr)
DF <- data.frame('ID'=c(1, 1, 1, 2, 2, 2),
'A'=c(1, 2, 3, 4, 5, 6),
'B'=c(2, 4, 6, 8, 10, 12))
IDgp <- group_by(DF, ID) %>%
summarise(C = prod(B) / sum(A))
### # Output:
###
### > DF
### ID A B
### 1 1 1 2
### 2 1 2 4
### 3 1 3 6
### 4 2 4 8
### 5 2 5 10
### 6 2 6 12
###
### > IDgp
### # A tibble: 2 x 2
### ID C
### <dbl> <dbl>
### 1 1 8
### 2 2 64
在这个例子中,我对 DF 中的 ID 列进行分组,并根据 A 列和 B 列创建一个任意的新变量。有没有一种直接的方法可以使用 [ 将这个例子转换为 Python =18=]?
您可以使用 GroupBy.apply
:
df = df.groupby('ID').apply(lambda x: x['B'].prod() / x['A'].sum()).reset_index(name='C')
print (df)
ID C
0 1 8.0
1 2 64.0
GroupBy.prod
and GroupBy.sum
, divide by Series.div
的另一个解决方案:
g = df.groupby('ID')
df = g['B'].prod().div(g['A'].sum()).reset_index(name='C')
print (df)
ID C
0 1 8.0
1 2 64.0
等同于:
df = df.groupby('ID')['B'].prod().div(df.groupby('ID')['A'].sum()).reset_index(name='C')
print (df)
ID C
0 1 8.0
1 2 64.0
apply
jezrael 提到的方法是要走的路。
或者,如果您想存储中间结果并通过链接分配新值,您可以使用 .agg
和 .assign
。
In [251]: df.groupby('ID').agg({'A': 'sum', 'B': 'prod'}).assign(C=lambda x: x.B/x.A)
Out[251]:
A B C
ID
1 6 48 8.0
2 15 960 64.0
我正在尝试从 R 的 dplyr 切换到 Python 中的 pandas。我已经通过几个教程来学习基础知识,但我坚持完成一项任务。我想使用 groupby 中的 agg 方法对多个列执行操作。这是 R 中的一项微不足道的任务,如下例所示:
library(dplyr)
DF <- data.frame('ID'=c(1, 1, 1, 2, 2, 2),
'A'=c(1, 2, 3, 4, 5, 6),
'B'=c(2, 4, 6, 8, 10, 12))
IDgp <- group_by(DF, ID) %>%
summarise(C = prod(B) / sum(A))
### # Output:
###
### > DF
### ID A B
### 1 1 1 2
### 2 1 2 4
### 3 1 3 6
### 4 2 4 8
### 5 2 5 10
### 6 2 6 12
###
### > IDgp
### # A tibble: 2 x 2
### ID C
### <dbl> <dbl>
### 1 1 8
### 2 2 64
在这个例子中,我对 DF 中的 ID 列进行分组,并根据 A 列和 B 列创建一个任意的新变量。有没有一种直接的方法可以使用 [ 将这个例子转换为 Python =18=]?
您可以使用 GroupBy.apply
:
df = df.groupby('ID').apply(lambda x: x['B'].prod() / x['A'].sum()).reset_index(name='C')
print (df)
ID C
0 1 8.0
1 2 64.0
GroupBy.prod
and GroupBy.sum
, divide by Series.div
的另一个解决方案:
g = df.groupby('ID')
df = g['B'].prod().div(g['A'].sum()).reset_index(name='C')
print (df)
ID C
0 1 8.0
1 2 64.0
等同于:
df = df.groupby('ID')['B'].prod().div(df.groupby('ID')['A'].sum()).reset_index(name='C')
print (df)
ID C
0 1 8.0
1 2 64.0
apply
jezrael 提到的方法是要走的路。
或者,如果您想存储中间结果并通过链接分配新值,您可以使用 .agg
和 .assign
。
In [251]: df.groupby('ID').agg({'A': 'sum', 'B': 'prod'}).assign(C=lambda x: x.B/x.A)
Out[251]:
A B C
ID
1 6 48 8.0
2 15 960 64.0