Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/80.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python相当于groupby mutate_Python_R_Pandas_Dplyr - Fatal编程技术网

Python相当于groupby mutate

Python相当于groupby mutate,python,r,pandas,dplyr,Python,R,Pandas,Dplyr,因此,在R中,当我有一个由4列组成的数据框,称之为df,我想通过一个组的和积来计算比率,我可以这样做: // generate data df = data.frame(a=c(1,1,0,1,0),b=c(1,0,0,1,0),c=c(10,5,1,5,10),d=c(3,1,2,1,2)); | a b c d | | 1 1 10 3 | | 1 0 5 1 | | 0 0 1 2 | | 1 1 5 1 | | 0

因此,在R中,当我有一个由4列组成的数据框,称之为df,我想通过一个组的和积来计算比率,我可以这样做:

// generate data
df = data.frame(a=c(1,1,0,1,0),b=c(1,0,0,1,0),c=c(10,5,1,5,10),d=c(3,1,2,1,2));
| a   b   c    d |
| 1   1   10   3 |
| 1   0   5    1 |
| 0   0   1    2 |
| 1   1   5    1 |
| 0   0   10   2 |
// compute sum product ratio
df = df%>% group_by(a,b) %>%
      mutate(
          ratio=c/sum(c*d)
      );
| a   b   c    d  ratio |
| 1   1   10   3  0.286 |
| 1   1   5    1  0.143 |
| 1   0   5    1  1     |
| 0   0   1    2  0.045 |
| 0   0   10   2  0.454 |
但在python中,我需要求助于循环。
我知道python中应该有一种比原始循环更优雅的方式,有人有什么想法吗

可以使用与
groupby()
apply()
类似的语法来完成:

根据这一点,我们可以使用
transform()
方法复制
dplyr::groupby()
dplyr::mutate()
的组合。对于本例,它将如下所示:

df=pd.DataFrame(
口述(
a=(1,1,0,1,0),
b=(1,0,0,1,0),
c=(10,5,1,5,10),
d=(3,1,2,1,2),
)
).分配(
prod_c_d=lambda x:x['c']*x['d'],
比率=λx:x['c']/(x.groupby(['a','b'])。转换('sum')['prod_c_d']))
)
本例使用。有关如何使用方法链接复制
dplyr
工作流的更多信息,请参见此

使用
apply()
groupby()。例如,如果我们从lambda表达式中删除
g.c/
,则它不起作用

df['ratio'] = df.groupby(['a','b'], group_keys=False)\
    .apply(lambda g: (g.c * g.d).sum() )

group_keys=False实现了什么?默认情况下,
groupby()
将组列作为额外索引添加到结果中,这使得其索引不同于原始数据帧,因此无法轻松为其分配数据帧。避免将组列添加为键,这样,只要每一行都有唯一的索引,就可以进行赋值。好吧,这和mutate一样实用。mutate的最大优点是,您可以在pipiline中创建一个新变量并保持链接,而这需要您专门指定一行来指定新列。难道没有一个“inplace=True”的方法来为panda创建一个额外的列吗?如果我们想在同一个调用中分配两个以上的列,每个列都使用
.groupby(['a','b'])
?有没有比像这样对每一列重复groupby方法更“整洁”的方法
df=df.assign(c_lag1=lambda x:x['c'].groupby(['a','b']).shift(-1),c_lag2=lambda x:x['c'].groupby(['a','b']).shift(-2))
您能否进一步解释为什么我们需要
分配
中的
lambda
?我搞不懂
x
指的是什么。原始
DataFrame
或某些子组?lambda表达式是编写一行一个关键字函数的方法。在
assign
方法
x
中使用它时,调用原始数据帧,其中包含当前方法链上游已经进行的所有更改。这仍然是最好的方法吗?在熊猫1.0中有更好的方法吗?…,这种方法是我发现的最好的方法,但是它似乎不是很有效(当你只需要一列时,对所有列进行转换('sum'))。mutate的另一个真正强大的部分是不需要作用域,你可以简单地编写c/sum(cd)它知道它指的是来自左边的数据帧。我觉得用python编写lambda g:g.c/(g.cg.d).sum()@jedi是没有必要的冗长和混乱的,我同意,但当你不得不使用python时,你无能为力。。。
df['ratio'] = df.groupby(['a','b'], group_keys=False)\
    .apply(lambda g: (g.c * g.d).sum() )