Pandas-18.分组

2019-05-29 17:17:00 浏览数 (1)

Pandas-18.分组

  • 任何分组操作都涉及原始对象的以下操作之一:
    • 分割对象
    • 应用一个函数
    • 结合的结果
  • 将数据分组之后,每个自己可以执行以下种类的操作:
    • 聚合 - 计算汇总统计
    • 转换 - 执行特定于组的操作
    • 过滤

以如下代码作为例子:

代码语言:javascript复制
import pandas as pd
ipl_data = {'Team': ['Riders', 'Riders', 'Devils', 'Devils', 'Kings',
         'kings', 'Kings', 'Kings', 'Riders', 'Royals', 'Royals', 'Riders'],
         'Rank': [1, 2, 2, 3, 3,4 ,1 ,1,2 , 4,1,2],
         'Year': [2014,2015,2014,2015,2014,2015,2016,2017,2016,2014,2015,2017],
         'Points':[876,789,863,673,741,812,756,788,694,701,804,690]}
df = pd.DataFrame(ipl_data)
'''
      Team  Rank  Year  Points
0   Riders     1  2014     876
1   Riders     2  2015     789
2   Devils     2  2014     863
3   Devils     3  2015     673
4    Kings     3  2014     741
5    kings     4  2015     812
6    Kings     1  2016     756
7    Kings     1  2017     788
8   Riders     2  2016     694
9   Royals     4  2014     701
10  Royals     1  2015     804
11  Riders     2  2017     690
'''

拆成分组

  • obj.groupby(‘key’) - 单条件分组
  • obj.groupby([‘key1’,’key2’]) - 多条件分组
  • obj.groupby(key,axis=1) - 换轴分组
代码语言:javascript复制
print (df.groupby(['Team',"Year"]))
# <pandas.core.groupby.generic.DataFrameGroupBy object at 0x108aab278>

查看分组

代码语言:javascript复制
print (df.groupby('Team').groups)
'''
{'Devils': Int64Index([2, 3], dtype='int64'), 'Kings': Int64Index([4, 6, 7], dtype='int64'), 'Riders': Int64Index([0, 1, 8, 11], dtype='int64'), 'Royals': Int64Index([9, 10], dtype='int64'), 'kings': Int64Index([5], dtype='int64')}
'''

迭代遍历分组

默认groupby对象具有分组名相同的标签名称

代码语言:javascript复制
for name,group in  df.groupby('Year'):
    print (name)
    print (group)
'''
2014
     Team  Rank  Year  Points
0  Riders     1  2014     876
2  Devils     2  2014     863
4   Kings     3  2014     741
9  Royals     4  2014     701
2015
      Team  Rank  Year  Points
1   Riders     2  2015     789
3   Devils     3  2015     673
5    kings     4  2015     812
10  Royals     1  2015     804
2016
     Team  Rank  Year  Points
6   Kings     1  2016     756
8  Riders     2  2016     694
2017
      Team  Rank  Year  Points
7    Kings     1  2017     788
11  Riders     2  2017     690
'''

选择一个分组

get_group()方法可以选择一个分组:

代码语言:javascript复制
print (df.groupby('Year').get_group(2014))
'''
     Team  Rank  Year  Points
0  Riders     1  2014     876
2  Devils     2  2014     863
4   Kings     3  2014     741
9  Royals     4  2014     701
'''

聚合

创建分组之后,可以在此基础上为每个分组返回单个聚合值:

代码语言:javascript复制
import numpy as np
print (df.groupby('Team').agg(np.size))
'''
        Rank  Year  Points
Team                      
Devils     2     2       2
Kings      3     3       3
Riders     4     4       4
Royals     2     2       2
kings      1     1       1
'''

可以使用多个聚合函数

代码语言:javascript复制
print (df.groupby('Team').agg([np.size, np.sum,np.std]))
'''
       Rank               Year                 Points                  
       size sum       std size   sum       std   size   sum         std
Team                                                                   
Devils    2   5  0.707107    2  4029  0.707107      2  1536  134.350288
Kings     3   5  1.154701    3  6047  1.527525      3  2285   24.006943
Riders    4   7  0.500000    4  8062  1.290994      4  3049   88.567771
Royals    2   5  2.121320    2  4029  0.707107      2  1505   72.831998
kings     1   4       NaN    1  2015       NaN      1   812         NaN
'''

转换

transform()方法可以对分组进行转换,返回与分组相同大小的结果。

代码语言:javascript复制
print (df.groupby('Team').transform(lambda x: x / 2))
'''
    Rank    Year  Points
0    0.5  1007.0   438.0
1    1.0  1007.5   394.5
2    1.0  1007.0   431.5
3    1.5  1007.5   336.5
4    1.5  1007.0   370.5
5    2.0  1007.5   406.0
6    0.5  1008.0   378.0
7    0.5  1008.5   394.0
8    1.0  1008.0   347.0
9    2.0  1007.0   350.5
10   0.5  1007.5   402.0
11   1.0  1008.5   345.0
'''

过滤

filter()方法用于过滤数据

代码语言:javascript复制
print(df.groupby('Team').filter(lambda x:  len(x) > 3))
'''
      Team  Rank  Year  Points
0   Riders     1  2014     876
1   Riders     2  2015     789
8   Riders     2  2016     694
11  Riders     2  2017     690
'''

参加三次以上IPL的队伍

0 人点赞