pandas中dummy summarize/aggregate by multiple functions的等价物是什么?

67up9zun  于 11个月前  发布在  其他
关注(0)|答案(3)|浏览(66)

我想将我的R代码使用dplyr包转换为pandas,在那里我分组并执行多个摘要。
下面是我的当前代码:

import pandas as pd
data = pd.DataFrame(
    {'col1':[1,1,1,1,1,2,2,2,2,2],
    'col2':[1,2,3,4,5,6,7,8,9,0],
     'col3':[-1,-2,-3,-4,-5,-6,-7,-8,-9,0]
    }
)
result = []
for k,v in data.groupby('col1'):
    result.append([k, max(v['col2']), min(v['col3'])])
print pd.DataFrame(result, columns=['col1', 'col2_agg', 'col3_agg'])

字符串
问题:

  • 太冗长
  • 可能可以优化和高效。(我将一个for-loop groupby实现重写为groupby.agg,性能增强是巨大的)。

在R中,等价的代码是:

data %>% groupby(col1) %>% summarize(col2_agg=max(col2), col3_agg=min(col3))


另外,groupby().summarize(newcolumn=max(col2 * col3))的等价物是什么,即函数是2+列的复合函数的聚合/汇总?

lymnna71

lymnna711#

相当于

df %>% groupby(col1) %>% summarize(col2_agg=max(col2), col3_agg=min(col3))

字符串

df.groupby('col1').agg({'col2': 'max', 'col3': 'min'})


它返回

col2  col3
col1            
1        5    -5
2        9    -9


返回的对象是一个pandas.DataFrame,其索引名为col1,列名为col2col3。默认情况下,当您对数据pandas进行分组时,会将分组列设置为索引,以实现高效的访问和修改。但是,如果您不希望这样,有两种方法可以将col1设置为列。

  • 通过as_index=False
df.groupby('col1', as_index=False).agg({'col2': 'max', 'col3': 'min'})

  • 调用reset_index
df.groupby('col1').agg({'col2': 'max', 'col3': 'min'}).reset_index()


屈服

col1  col2  col3           
   1     5    -5
   2     9    -9


您还可以将多个函数传递给groupby.agg

agg_df = df.groupby('col1').agg({'col2': ['max', 'min', 'std'], 
                                 'col3': ['size', 'std', 'mean', 'max']})


这也返回一个DataFrame,但现在它有一个列的MultiIndex。

col2               col3                   
      max min       std size       std mean max
col1                                           
1       5   1  1.581139    5  1.581139   -3  -1
2       9   0  3.535534    5  3.535534   -6   0

MultiIndex对于选择和分组非常方便。下面是一些例子:

agg_df['col2']  # select the second column
      max  min       std
col1                    
1       5    1  1.581139
2       9    0  3.535534

agg_df[('col2', 'max')]  # select the maximum of the second column
Out: 
col1
1    5
2    9
Name: (col2, max), dtype: int64

agg_df.xs('max', axis=1, level=1)  # select the maximum of all columns
Out: 
      col2  col3
col1            
1        5    -1
2        9     0

在早期(0.20.0之前的版本),可以使用字典来重命名agg调用中的列。

df.groupby('col1')['col2'].agg({'max_col2': 'max'})

将返回第二列的最大值max_col2

max_col2
col1          
1            5
2            9

然而,它被弃用,转而支持rename方法:

df.groupby('col1')['col2'].agg(['max']).rename(columns={'max': 'col2_max'})

      col2_max
col1          
1            5
2            9

对于像上面定义的agg_df这样的DataFrame,它可能会变得冗长。在这种情况下,您可以使用重命名函数来扁平化这些级别:

agg_df.columns = ['_'.join(col) for col in agg_df.columns]

      col2_max  col2_min  col2_std  col3_size  col3_std  col3_mean  col3_max
col1                                                                        
1            5         1  1.581139          5  1.581139         -3        -1
2            9         0  3.535534          5  3.535534         -6         0

对于像groupby().summarize(newcolumn=max(col2 * col3))这样的操作,您仍然可以通过首先使用assign添加一个新列来使用agg。

df.assign(new_col=df.eval('col2 * col3')).groupby('col1').agg('max') 

      col2  col3  new_col
col1                     
1        5    -1       -1
2        9     0        0

这将返回新列和旧列的最大值,但您可以一如既往地对其进行切片。

df.assign(new_col=df.eval('col2 * col3')).groupby('col1')['new_col'].agg('max')

col1
1   -1
2    0
Name: new_col, dtype: int64

如果是groupby.apply,则会更短:

df.groupby('col1').apply(lambda x: (x.col2 * x.col3).max())

col1
1   -1
2    0
dtype: int64

但是,groupby.apply将其视为自定义函数,因此不会对其进行向量化。('min','max','min','size'等)是矢量化的,这些是优化函数的别名。您可以将df.groupby('col1').agg('min')替换为df.groupby('col1').agg(min)df.groupby('col1').agg(np.min)df.groupby('col1').min(),它们都将执行相同的函数。当您使用自定义函数时,您不会看到相同的效率。
最后,从0.20版本开始,agg可以直接在DataFrames上使用,而不必先分组。参见示例here

von4xj4u

von4xj4u2#

使用datar将R代码转换为python代码非常容易,而无需学习pandas的API:

>>> from datar import f
>>> from datar.tibble import tibble
>>> from datar.dplyr import group_by, summarize
>>> from datar.base import min, max
>>> data = tibble(
...     col1=[1,1,1,1,1,2,2,2,2,2],
...     col2=[1,2,3,4,5,6,7,8,9,0],
...     col3=[-1,-2,-3,-4,-5,-6,-7,-8,-9,0]
... )
>>> data >> group_by(f.col1) >> summarize(col2_agg=max(f.col2), col3_agg=min(f.col3))
   col1  col2_agg  col3_agg
0     1         5        -5
1     2         9        -9

字符串
我是软件包的作者。如果您有任何问题,请随时提交问题。

5jvtdoz2

5jvtdoz23#

查看Pandas文档中给出的并排比较:http://pandas.pydata.org/pandas-docs/stable/comparison_with_r.html#grouping-and-summarizing
R's débér

gdf <- group_by(df, col1)
summarise(gdf, avg=mean(col1, na.rm=TRUE))

字符串
Pandas

gdf = df.groupby('col1')
df.groupby('col1').agg({'col1': 'mean'})

相关问题