pandas groupby 详解

来源:互联网 发布:政府数据开放平台 编辑:程序博客网 时间:2024/06/06 08:55

NameBrandClothCountgirluniqlsweater3girletamsuit1girletampants1girllagogojacket2boypants2boyhailant-shirt1motherhengyuanxiangcoat2motherhengyuanxiangsweater1mothercoat1fatherhailant-shirt2fatherhailansweater1fatherhailanpants3


本文数据源如上,Name:在家庭中的身份, Brand:衣服品牌, ClothType:衣服数量,Count:衣服数量

import pandas as pddata=pd.read_excel('testdata.xlsx')
如果是csv文件:
import pandas as pddata=pd.read_csv('testdata.csv',sep=',')
查看data的内容:
dataOut[1]:       Name          Brand    Cloth  Count0     girl          uniql  sweater      31     girl           etam     suit      12     girl           etam    pants      13     girl         lagogo   jacket      24      boy            NaN    pants      25      boy         hailan  t-shirt      16   mother  hengyuanxiang     coat      27   mother  hengyuanxiang  sweater      18   mother            NaN     coat      19   father         hailan  t-shirt      210  father         hailan  sweater      111  father         hailan    pants      3


获取列名:
data.columnsOut[2]: Index(['Name', 'Brand', 'Cloth', 'Count'], dtype='object')data.columns[0]Out[2]: 'Name'data.columns[1]Out[3]: 'Brand'
获取index:
data.indexOut[3]: RangeIndex(start=0, stop=12, step=1)

从0开始,到12停,不包括12.所以一共有12行数据
获取values:
data.valuesOut[4]: array([['girl', 'uniql', 'sweater', 3],       ['girl', 'etam', 'suit', 1],       ['girl', 'etam', 'pants', 1],       ['girl', 'lagogo', 'jacket', 2],       ['boy', nan, 'pants', 2],       ['boy', 'hailan', 't-shirt', 1],       ['mother', 'hengyuanxiang', 'coat', 2],       ['mother', 'hengyuanxiang', 'sweater', 1],       ['mother', nan, 'coat', 1],       ['father', 'hailan', 't-shirt', 2],       ['father', 'hailan', 'sweater', 1],       ['father', 'hailan', 'pants', 3]], dtype=object)

获取某一行:
data.values[1]Out[5]: array(['girl', 'etam', 'suit', 1], dtype=object)
获取某一格:
data.values[1][2]Out[6]: 'suit'

按某一列关键字分组:
gp=data.groupby('Brand')#写data.groupby(data['Brand'])也是一样的gpOut[10]: <pandas.core.groupby.DataFrameGroupBy object at 0x0000000008309B38>type(gp)Out[11]: pandas.core.groupby.DataFrameGroupBy

gp是一个把dataframe groupby以后的对象,它实际上还没有进行任何计算,只是一个暂时存储的容器。
对这个暂时存储的容器进行计数,因为是按'Brand'分的组,:
gp.count()Out[13]:                Name  Cloth  CountBrand                            etam              2      2      2hailan            4      4      4hengyuanxiang     2      2      2lagogo            1      1      1uniql             1      1      1

看到按'Brand'分组后的这个结果,Name,Cloth,Count列在每种Brand所对应行的数字都一样,比如:2 2 2.可以理解为每种Brand各有多少行数据,把这个行数显示在所有列。
因为我们选择时是data.groupby(),而不是data['Count'].groupby()
p.s.:可以看到分组计数后的index是'Brand‘,这是因为分组是按'Brand’字段分的

gp.count().indexOut[14]: Index(['etam', 'hailan', 'hengyuanxiang', 'lagogo', 'uniql'], dtype='object', name='Brand')

想知道每种Brand的衣服有多少人穿多少种,其实只看 Count列就行了。
比如father虽然有2件T-shirt,1件sweater,3件pants,还是算1个人穿3种hailan。boy有一件hailan的t-shirt,算1个人穿1种hailan。所以hailan对应4。 总之,count()函数可以理解为对Count列去重的和。
gp1=data['Count'].groupby(data['Brand'])gp1.count() #和gp1.size()结果一样Out[20]: Brandetam             2hailan           4hengyuanxiang    2lagogo           1uniql            1Name: Count, dtype: int64

想求某品牌被人均拥有的件数的平均值:
比如hailan就是father的2件T恤,1件毛衣,3条裤子,还有boy的1件T恤。 (2+1+3+1)/4=1.75。 分母4可以理解为刚才所说的 gp1.count() :每种Brand的衣服有多少人穿多少种
比如hengyuanxiang就是mother的2件大衣,1件毛衣 ,(2+1)/2=1.5
gp1.mean()Out[21]: Brandetam             1.00hailan           1.75hengyuanxiang    1.50lagogo           2.00uniql            3.00Name: Count, dtype: float64
说明:type(gp1.mean())  是 Series类型。之所以index叫'Brand',是因为原datafram是按'Brand' groupby的


想求某品牌被每人拥有的件数:(与“”想知道每种Brand的衣服有多少人穿多少种“ .count( )算法的区别在于 不去重)
在Count列上加和
gp1.agg(sum) #就是 data['Count'].groupby(data['Brand']).agg(sum) , agg里也可以写'sum',与不加单引号等效Out[5]: Brandetam             2hailan           7hengyuanxiang    3lagogo           2uniql            3Name: Count, dtype: int64

综上所述可以观察出,gp1.mean()操作的结果等于 gp1.agg(sum)/gp1.count()

遍历分组:

for name,group in data.groupby(data['Brand']):    print(name)    print(group)    etam   Name Brand  Cloth  Count1  girl  etam   suit      12  girl  etam  pants      1hailan      Name   Brand    Cloth  Count5      boy  hailan  t-shirt      19   father  hailan  t-shirt      210  father  hailan  sweater      111  father  hailan    pants      3hengyuanxiang     Name          Brand    Cloth  Count6  mother  hengyuanxiang     coat      27  mother  hengyuanxiang  sweater      1lagogo   Name   Brand   Cloth  Count3  girl  lagogo  jacket      2uniql   Name  Brand    Cloth  Count0  girl  uniql  sweater      3

由上可以看出,brand为NaN 的衣服并没有被分组,自动忽略不计了。



对于由DataFrame产生的GroupBy对象,如果用一个(单个字符串)或一组(字符串数组)列名对其进行索引,就能实现选取部分列进行聚合的目的,即:

写法一:

data.groupby('Brand')['Count'].sum()#等价于data.groupby('Brand')['Count'].agg(sum),等价于data.groupby('Brand')['Count'].agg('sum')#等价于data.groupby('Brand').agg('sum')['Count'],等价于data.groupby('Brand').agg(sum)['Count'],等价于data.groupby('Brand').sum()['Count']Out[13]: Brandetam             2hailan           7hengyuanxiang    3lagogo           2uniql            3Name: Count, dtype: int64

这和写法二:

data['Count'].groupby(data['Brand']).sum()Out[19]: Brandetam             2hailan           7hengyuanxiang    3lagogo           2uniql            3Name: Count, dtype: int64

是等效的


注意写法一里面的'Brand'不用必须写成(当然也可以写成)data['Brand'],是因为data.groupby()由于是对data这个dataframe调用的方法,所以能识别出data的字段'Brand'。但是写法二是对data['Count'] 这个Series对象调用的groupby,不认识'Brand',只认识data['Brand'],如果写法二还写成.groupby('Brand')就会报错。


双索引分组:

想知道每人拥有每种品牌的衣服多少种类型(类型就是Cloth字段,写成ClothType大家更容易理解哈):

data.groupby(['Name','Brand'])['Count'].count() #和写.size( )效果一样Out[31]: Name    Brand        boy     hailan           1father  hailan           3girl    etam             2        lagogo           1        uniql            1mother  hengyuanxiang    2Name: Count, dtype: int64

从结果可以看出,对boy拥有的没Brand的一条裤子,和mother没牌子的一件大衣,都自动忽略不计了。



最后,感谢http://blog.csdn.net/leonis_v/article/details/51832916的分享

原创粉丝点击