使用tidydata原则在pandas/python中使用Groupby mutate等效

使用tidydata原则在pandas/python中使用Groupby mutate等效,python,r,pandas,dplyr,Python,R,Pandas,Dplyr,我的数据框类似于以下内容: group_var1 = ['A1','A1', 'A1', 'A1', 'A1', 'A1', 'A1', 'A1', 'A2', 'A2', 'A2', 'A2', 'A2', 'A2', 'A2', 'A2'] group_var2 = ['B1', 'B1', 'B1', 'B1', 'B2', 'B2', 'B2', 'B2', 'B1', 'B1', 'B1', 'B1', 'B2', 'B2', 'B2', 'B2'] group_var3 = ['C1

我的数据框类似于以下内容:

group_var1 = ['A1','A1', 'A1', 'A1', 'A1', 'A1', 'A1', 'A1', 'A2', 'A2', 'A2', 'A2', 'A2', 'A2', 'A2', 'A2']
group_var2 = ['B1', 'B1', 'B1', 'B1', 'B2', 'B2', 'B2', 'B2', 'B1', 'B1', 'B1', 'B1', 'B2', 'B2', 'B2', 'B2']
group_var3 = ['C1', 'C2', 'C1', 'C2', 'C1', 'C2', 'C1', 'C2', 'C1', 'C2', 'C1', 'C2', 'C1', 'C2', 'C1', 'C2']

value = np.arange(len(group_var1))

ex_df = pd.DataFrame({
    'group_var1' : group_var1,
    'group_var2' : group_var2,
    'group_var3' : group_var3,
    'value' : value
})

调用时,应生成以下内容:

    group_va1   group_va2   group_va3   value
0   A1  B1  C1  0
1   A1  B1  C2  1
2   A1  B1  C1  2
3   A1  B1  C2  3
4   A1  B2  C1  4
5   A1  B2  C2  5
6   A1  B2  C1  6
7   A1  B2  C2  7
8   A2  B1  C1  8
9   A2  B1  C2  9
10  A2  B1  C1  10
11  A2  B1  C2  11
12  A2  B2  C1  12
13  A2  B2  C2  13
14  A2  B2  C1  14
15  A2  B2  C2  15

我的目标是按列
group\u var1
group\u var2
group\u var3
对数据帧进行分组,然后计算每个组内的平均
,并使用这些结果向现有数据帧添加新行
mean\u ex
。在R中,这可以通过
ex_df%>%group_by(c(group_var1,group_var2,group_var3))%>%mutate(mean_ex=mean(value))
来实现,它自动处理将新值分配给相应行的操作

我已经找到了通过将每个组中的所有值聚合为平均值(
ex_df.groupby(['group_var1','group_var2','group_var3']).mean()
)来总结数据帧的方法,但我希望平均值是现有数据帧中的一个新列,而不是更小维度的df。我想要的输出可以在下面找到,并且是通过在我的原始df和之前描述的不想要的聚合表上使用pd.merge()实现的:


    group_var1  group_var2  group_var3  value   mean_ex
0   A1  B1  C1  0   1
1   A1  B1  C2  1   2
2   A1  B1  C1  2   1
3   A1  B1  C2  3   2
4   A1  B2  C1  4   5
5   A1  B2  C2  5   6
6   A1  B2  C1  6   5
7   A1  B2  C2  7   6
8   A2  B1  C1  8   9
9   A2  B1  C2  9   10
10  A2  B1  C1  10  9
11  A2  B1  C2  11  10
12  A2  B2  C1  12  13
13  A2  B2  C2  13  14
14  A2  B2  C1  14  13
15  A2  B2  C2  15  14


我的问题是,有没有任何方法可以在不创建单独的数据帧然后合并回原始数据帧的情况下实现所需的输出?谢谢。

使用
转换
分配

ex_df.assign(
    mean_val = 
    ex_df
    .groupby(["group_var1", "group_var2",  "group_var3"])
    .value
    .transform('mean')
)

   group_var1 group_var2 group_var3  value  mean_val
0          A1         B1         C1      0         1
1          A1         B1         C2      1         2
2          A1         B1         C1      2         1
3          A1         B1         C2      3         2
4          A1         B2         C1      4         5
5          A1         B2         C2      5         6
6          A1         B2         C1      6         5
7          A1         B2         C2      7         6
8          A2         B1         C1      8         9
9          A2         B1         C2      9        10
10         A2         B1         C1     10         9
11         A2         B1         C2     11        10
12         A2         B2         C1     12        13
13         A2         B2         C2     13        14
14         A2         B2         C1     14        13
15         A2         B2         C2     15        14
解释
Pandas
assign
大致相当于
dplyr::mutate
transform
在输入的所有初始行上广播分组操作,而不是在
groupby
之后简单地调用聚合函数


类似于
df.groupby('a').x.mean()
的内容将为每个分组索引集生成一个值,该值类似于
dplyr::summary

Use
transform
assign

ex_df.assign(
    mean_val = 
    ex_df
    .groupby(["group_var1", "group_var2",  "group_var3"])
    .value
    .transform('mean')
)

   group_var1 group_var2 group_var3  value  mean_val
0          A1         B1         C1      0         1
1          A1         B1         C2      1         2
2          A1         B1         C1      2         1
3          A1         B1         C2      3         2
4          A1         B2         C1      4         5
5          A1         B2         C2      5         6
6          A1         B2         C1      6         5
7          A1         B2         C2      7         6
8          A2         B1         C1      8         9
9          A2         B1         C2      9        10
10         A2         B1         C1     10         9
11         A2         B1         C2     11        10
12         A2         B2         C1     12        13
13         A2         B2         C2     13        14
14         A2         B2         C1     14        13
15         A2         B2         C2     15        14
解释
Pandas
assign
大致相当于
dplyr::mutate
transform
在输入的所有初始行上广播分组操作,而不是在
groupby
之后简单地调用聚合函数

类似于
df.groupby('a').x.mean()
的内容将为每个分组索引set生成一个值,这类似于
dplyr::summary