编程语言
首页 > 编程语言> > python – 多个函数的pdas等效于dplyr汇总/聚合是什么?

python – 多个函数的pdas等效于dplyr汇总/聚合是什么?

作者:互联网

我有从R转换到pandas的问题,其中dplyr包可以轻松分组并执行多个汇总.

请帮助改进我现有的Python 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循环groupby实现重写为groupby.agg并且性能增强很大).

在R中,等效代码为:

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

更新:@ayhan解决了我的问题,这是一个后续问题,我将在这里发布而不是评论:

Q2)groupby()的等价物总结(newcolumn = max(col2 * col3)),即聚合/汇总,其中函数是2列的复合函数?

解决方法:

相当于

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,列名为col2和col3.默认情况下,对数据进行分组时,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

早些时候(version 0.20.0之前)可以使用字典重命名agg调用中的列.例如

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

将返回第二列的最大值为max_col2:

      max_col2
col1          
1            5
2            9

但是,它被弃用以支持重命名方法:

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将此视为自定义函数,因此不会进行矢量化.到目前为止,我们传递给agg(‘min’,’max’,’min’,’size’等)的函数是矢量化的,这些是这些优化函数的别名.你可以用df.groupby(‘col1’)替换df.groupby(‘col1’).agg(‘min’).agg(min),df.groupby(‘col1’).agg(np.min)或df .groupby(‘col1’).min(),它们都将执行相同的功能.使用自定义函数时,您将看不到相同的效率.

最后,从版本0.20开始,agg可以直接在DataFrame上使用,而不必先进行分组.见例子here.

标签:pandas-groupby,python,r,pandas,summarize
来源: https://codeday.me/bug/20191003/1850826.html