Skip to main content
 首页 » 编程设计

python之如何在 Pandas 中做 R dplyr

2025年05月04日24xing901022

我想将我的 pandas DataFrame 分成几组,然后在每个 block 上运行一个复杂的函数。复杂函数为每个 block 返回一个具有任意数量和名称的列以及任意数量的行的 DataFrame。我希望这些结果 DataFrame 在操作后合并。在 R 中,我可以用

library(tibble) 
library(dplyr) 
 
df = tribble( 
  ~g,  ~c1, ~c2, 
  "a",   1,   6, 
  "a",   2,   7, 
  "b",   3,   8, 
  "b",   4,   9, 
  "b",   5,  10 
) 
 
myfct <- function(x, y){ 
  data.frame(c1 = x, 
             c2 = y, 
             res = c(x * y, x + y, x / y), 
             type = c('mult', 'add', 'div')) 
} 
 
df %>% group_by(g) %>% do(myfct(.$c1, .$c2)) 

结果是

Source: local data frame [15 x 5] 
Groups: g [2] 
 
       g    c1    c2        res   type 
   <chr> <dbl> <dbl>      <dbl> <fctr> 
1      a     1     6  6.0000000   mult 
2      a     2     7 14.0000000    add 
3      a     1     6  7.0000000    div 
4      a     2     7  9.0000000   mult 
5      a     1     6  0.1666667    add 
6      a     2     7  0.2857143    div 
7      b     3     8 24.0000000   mult 
8      b     4     9 36.0000000    add 
9      b     5    10 50.0000000    div 
10     b     3     8 11.0000000   mult 
11     b     4     9 13.0000000    add 
12     b     5    10 15.0000000    div 
13     b     3     8  0.3750000   mult 
14     b     4     9  0.4444444    add 
15     b     5    10  0.5000000    div 

当然,这只是一个例子。

请您参考如下方法:

我认为您需要申请 - 同时检查 flexible apply :

def myfct(x): 
    print (x) 
    return pd.DataFrame({'mult':x['c1'] * x['c2'],  
                          'add':x['c1'] + x['c2'],  
                          'div':x['c1'] / x['c2'], 
                          'g':x.name, 
                          'c1': x['c1'], 
                          'c2':x['c2']}) 
 
df = df.groupby('g')['c1','c2'].apply(myfct) 
print (df) 
   add  c1  c2       div  g  mult 
0    7   1   6  0.166667  a     6 
1    9   2   7  0.285714  a    14 
2   11   3   8  0.375000  b    24 
3   13   4   9  0.444444  b    36 
4   15   5  10  0.500000  b    50 

也可以使用 reshape melt :

df = df.groupby('g')['c1','c2'].apply(myfct) 
       .melt(id_vars=['g','c1','c2'], value_name='res', var_name='type') 
print (df) 
    g  c1  c2  type        res 
0   a   1   6   add   7.000000 
1   a   2   7   add   9.000000 
2   b   3   8   add  11.000000 
3   b   4   9   add  13.000000 
4   b   5  10   add  15.000000 
5   a   1   6   div   0.166667 
6   a   2   7   div   0.285714 
7   b   3   8   div   0.375000 
8   b   4   9   div   0.444444 
9   b   5  10   div   0.500000 
10  a   1   6  mult   6.000000 
11  a   2   7  mult  14.000000 
12  b   3   8  mult  24.000000 
13  b   4   9  mult  36.000000 
14  b   5  10  mult  50.000000