panda数据处理:groupby()函数

xiaoxiao2025-09-17  38

     groupby()是pandas库中DataFrame结构的函数,最近在看用Movielens数据集进行关联分析的教程时,发现用到了groupby()函数,觉得该函数功能很强大,经常用在for循环结构中用于提取数据,故对该函数一些常用的方法进行一些记录。

      

     先创建一个DataFrame对象df

import pandas as pd df=pd.DataFrame({'name':['a','b','c','d','e'],'age':[10,15,20,15,20],'sex':[True,True,False,True,False]}) df >>> name age sex 0 a 10 True 1 b 15 True 2 c 20 False 3 d 15 True 4 e 20 False

 1.数据分组

  依据某个columns对整个DataFrame对象分组

df_1=df.groupby(df['sex']) list(df_1) >>> [(False, name age sex 2 c 20 False 4 e 23 False), (True, name age sex 0 a 10 True 1 b 15 True 3 d 17 True)]

   依据某个columns对另一个columns数据分组

df_1=df['age'].groupby(df['sex']) list(df_1) >>> [(False, 2 20 4 23 Name: age, dtype: int64), (True, 0 10 1 15 3 17 Name: age, dtype: int64)]

     这个过程还有另外一种语法

df_1=df.groupby(df['sex'])['age'] list(df_1) >>> [(False, 2 20 4 23 Name: age, dtype: int64), (True, 0 10 1 15 3 17 Name: age, dtype: int64)]

  当然,也可以同时对多个columns数据进行分组,以第一种语法方式为例,此时要注意多个columns的书写方式

df_1=df[['age','name']].groupby(df['sex']) list(df_1) >>> [(False, age name 2 20 c 4 23 e), (True, age name 0 10 a 1 15 b 3 17 d)]

  也可以依据多个columns对某个columns数据分组,注意这里groupby函数内columns的写法,不能再像上面那样了

df_1=df['name'].groupby([df['sex'],df['age']]) list(df_1) >>> [((False, 20), 2 c Name: name, dtype: object), ((False, 23), 4 e Name: name, dtype: object), ((True, 10), 0 a Name: name, dtype: object), ((True, 15), 1 b Name: name, dtype: object), ((True, 17), 3 d Name: name, dtype: object)]

  除了依据DataFrame结构中已有的columns对数据进行分组,还可以通过外部设定的columns对DataFrame数据进行分组

import numpy as np education=np.array(['mid school','high school','university','high school','university']) df_1=df.groupby([education]) list(df_1) >>> [('high school', name age sex 1 b 15 True 3 d 17 True), ('mid school', name age sex 0 a 10 True), ('university', name age sex 2 c 20 False 4 e 23 False)]

  通过groupby函数来分组时,还有一些别具创意的分组方式,任何被当做分组键的函数都会在各个索引值上被调用一次,其返回值就会被用作分组名称。例如对于所用的df,给它加上索引值index(国籍),然后依据国家名称英文字符的个数来分组

df.index=['China','Russia','USA','English','Japan'] df.groupby(len).sum() >>> age sex 3 20 False 5 30 True 6 15 True 7 15 True

 可以看到, ‘China’和'Japan'字母长度均为5,故在计算‘age’和'sex'时将其对应的值求和了,'age'不具有求和性质,未参与计算。

2.对分组进行迭代,生成字典

for index,group in df.groupby(df['sex'])['age']: print(index) print(group) >>> False 2 20 4 20 Name: age, dtype: int64 True 0 10 1 15 3 15 Name: age, dtype: int64

  在上面的程序中,index的输出为 ['False' , 'True'],group的输出结果为 [ ['20','20'] , ['10','15','15'] ]。一种常见的情况为用index、group的值生成字典。

dic=dict((index,frozenset(group.values))for index,group in df.groupby(df['sex'])['age']) dic >>> {False: frozenset({20}), True: frozenset({10, 15})}

在生成字典时,也会有多重键的情况,可以用以下方式

dic=dict(((index_1,index_2),frozenset(group.values))for (index_1,index_2),group in df['age'].groupby([df['sex'],df['age']])) dic >>> {(False, 20): frozenset({20}), (True, 10): frozenset({10}), (True, 15): frozenset({15})}

也可以用这种更为简洁的方式

dic=dict((index,frozenset(group.values))for index,group in df['age'].groupby([df['sex'],df['age']])) dic >>> {(False, 20): frozenset({20}), (True, 10): frozenset({10}), (True, 15): frozenset({15})}

还有另一种方式来生成字典

dic=dict( list(df.groupby('sex'))) dic >>> {False: name age sex 2 c 20 False 4 e 20 False, True: name age sex 0 a 10 True 1 b 15 True 3 d 15 True} dic[False]['name'] >>> 2 c 4 e Name: name, dtype: object

 这种对整个df生成字典的方式,字典每个键对应的值仍然为一个DataFrame结构。按照这种方式当然也可以用df中某个columns  生成字典。

   3.求和、平均计算

  数据处理时经常在groupby之后用到求和、平均计算,所以这里也顺带提一下。

  计算平均的过程为

df.groupby('sex')['age'].mean() >>> sex False 20.000000 True 13.333333 Name: age, dtype: float64

  求和的过程为

df.groupby('sex')['age'].sum() >>> sex False 40 True 40 Name: age, dtype: int64

       还有一种就是对DataFrame整个结构中各行或各列计算平均或求和,这里先引入pandas中轴(axis)的定义,在DataFrame中有axis=0和axis=1两种情况,axis=0表示遍历所有的行,不能理解为axis=0表示对列的操作,同样的,axis=1表示遍历所有的列。另外,在numpy库中也有关键字axis,且用法与pandas中一致。那么通过使用axis,求和、计算平均的过程可以为

df.sum(axis=1) >>> 0 11.0 1 16.0 2 20.0 3 16.0 4 20.0 dtype: float64 df.sum(axis=0) >>> name abcde age 80 sex 3 dtype: object df.mean(axis=0) >>> age 16.0 sex 0.6 dtype: float64

 

 

 

转载请注明原文地址: https://www.6miu.com/read-5036454.html

最新回复(0)