Python pandas相当于R groupby mutate

时间:2016-12-02 01:09:59

标签: 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   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中应该有一个比raw循环更优雅的方式,任何人都有任何想法?

3 个答案:

答案 0 :(得分:16)

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

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

documentation

答案 1 :(得分:2)

根据此thread on pandas github,我们可以使用transform()方法来复制dplyr::groupby()dplyr::mutate()的组合。对于此示例,其外观如下:

df = pd.DataFrame( dict( a=(1,1,0,1,0)
                        , b=(1,0,0,1,0)
                        , c=(10,5,1,5,10)
                        , d=(3,1,2,1,2) ) ) \
    .assign( prod_c_d = lambda x: x['c'] * x['d']
            , ratio = lambda x: x['c'] / x.groupby(['a','b']) \
                      .transform('sum')['prod_c_d']  )

此示例使用pandas method chaining。有关如何使用方法链来复制dplyr工作流的更多信息,请参见此blogpost

使用apply()groupby()的方法对我不起作用,因为它似乎无法适应。例如,如果我们从lambda表达式中删除g.c/,则无法正常工作。

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

答案 2 :(得分:0)

使用 datar 将您的 R 代码转换为 Python 非常容易:

toggle() {
    this.setState({displayMenu: !this.state.displayMenu});
    document.getElementById("menu").style.display = this.state.displayMenu ? "flex" : "none";
    console.log(this.state.displayMenu);
}

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