数据的分组,遍历,统计

俗话说:“人与类聚,物以群分”,到这里我们将学习数据的分组以及分组后统计。Pandas的分组相对于Excel会更加简单和灵活。

1️⃣分组

Pandas提供了一个灵活高效的groupby功能,它使你能以一种自然的方式对数据集进行切片、切块、摘要等操作。

✨效果
在这里插入图片描述

根据结果可以发现,分组后的结果为DataFrameGroupBy object,是一个分组后的对象。

用groupby的size方法可以查看分组后每组的数量,并返回一个含有分组大小的Series:

from pandas import Series,DataFrame

# 创建二维列表存储选手信息
lol_list = [['上单','Nuguri',31,78],
            ['打野','Tian',42,68],
            ['中单','Doinb',51,83],
            ['中单','Faker',38,76],
            ['ADC','Lwx',74,72],
            ['辅助','Crisp',53,69]]
# 创建dataframe
df = DataFrame(data=lol_list,
               index=['a','b','c','d','e','f'],
               columns=['位置','ID号','年龄','数据'])

groups = df.groupby('位置')
print('----------------------------------')

✨效果
在这里插入图片描述
根据上面的方法,我们就能得到每个位置的占比了,别犹豫,在下面的代码框中一试便知。

for i,j in groups.size().items():
    account = j/df.shape[0]
    dd="%.2f%%"%(account*100)
    print(f"{i}占比为{dd}")
print(groups.size())

✨效果

在这里插入图片描述
df.groupby(‘位置’)是根据位置列对整个数据进行分组,同样我们也可以只对一列数据进行分组,只保留我们需要的列数据。

例如:我们通过位置,只对年龄列数据进行分组。
group = df['年龄'].groupby(df['位置'])
# 查看分组
print(group.groups)
# 根据分组后的名字选择分组
print(group.get_group('中单'))

✨效果
在这里插入图片描述
1.代码group = df['年龄'].groupby(df['位置'])
它的逻辑是:取出df中年龄列数据,并且对该列数据根据df[‘位置’]列数据进行分组操作。

2.上一步的代码也可改写成group = df.groupby(df['位置'])['年龄']
它的逻辑是:将df数据通过df['位置']进行分组,然后再取出分组后的年龄列数据。两种写法达到的效果是一样的。

3.group.groups的结果是一个字典,字典的key是分组后每个组的名字,对应的值是分组后的数据,此方法方便我们查看分组的情况。

4.group.get_group(‘中单’)这个方法可以根据具体分组的名字获取,每个组的数据

2️⃣对分组进行遍历

上面我们通过groupby()和size()两个方法以及以前所学的一些技能计算出了各位置的占比。

那如果我们想加入进去呢,我们可以根据年龄来判断,groups.get_group(‘中单’)可以获取分组后某一个组的数据,'中单’为组的名字,这样我们就可以对某一个组进行处理。

from pandas import Series,DataFrame

# 创建二维列表存储选手信息
lol_list = [['韩国','上单','Nuguri',31,78],
            ['中国','打野','Tian',42,68],
            ['韩国','中单','Doinb',51,83],
            ['韩国','中单','Faker',38,76],
            ['中国','中单', 'xiye',21,45],
            ['中国','ADC','Lwx',74,72],
            ['中国','辅助','Crisp',53,69]]
# 创建dataframes
df = DataFrame(data=lol_list,
               index=['a','b','c','d','e','f','g'],
               columns=['国家','位置','ID号','年龄','数据'])


group = df.groupby(df['位置'])['年龄']
# 查看分组
print(group.groups)
# 根据分组后的名字选择分组
print(group.get_group('中单'))

在这里插入图片描述

通过上图我们可以得到中单的年龄,那么接下来我们就来算一算他们的平均年龄和最大最小年龄(这里样本数量较小,但是不影响操作)

group = df.groupby('位置')

# 根据分组后的名字选择分组
group_f = group.get_group('中单')
f_mean = group_f['年龄'].mean()
print(f_mean)

✨效果

在这里插入图片描述
🚩Pandas常用函数

函数意义
count()统计列表中非空数据的个数
nunique()统计非重复的数据的个数
sum()统计列表中所有数值的和
mean()计算列表中的数据的平均值
median()统计列表中的数据的中位数
max()求列表中数据的最大值
min()求列表中数据的最小值

其余的函数大家可以自行尝试

上面的代码成功的计算出了我们想要的数据,我们也可以遍历分组后的数据,并获取他们的最大年纪,最小年纪以及平均年龄。

group = df.groupby('位置')

for i,j in group:
    f_mean = j['年龄'].mean()
    print(f"{i}的平均年龄为{f_mean}")
# print(f_mean)

✨效果
在这里插入图片描述

3️⃣按多列进行分组

当我们需求更加的复杂时,若我们要对一组数据的对应的一个数据基础上划分,比如说我们要得到每个国家的位置的数量

按照上面的分析,难道我们要写两次groupby的分组操作?NO,我们强大的groupby()方法是支持按照多列进行分组。看下面

group = df.groupby(['国家','位置'])
df1=group.size()
print(df1)

✨效果

当需要按多列进行分组的时候,groupby方法里面我们传入的一个列表,列表中分别存储分组依据的列名。

注意:列表中列名的顺序,确定了先按国家列进行分组,然后再按位置列分组。不同的顺序,产生的分组名字是不同的。

那我们如何去获取里面的单个数据呢,group.size()返回的结果中发现索引值是多层的,那我们只需要一层一层的获取就行了
在这里插入图片描述

4️⃣对分组后数据进行统计

数据统计(也称为数据聚合)是数据处理的最后一步,通常是要使每一个数组生成一个单一的数值。

pandas提供了一个 agg( )方法用来对分组后的数据进行统计。

import pandas as pd
df = pd.read_excel('data.xlsx')
groups = df.groupby('gender')
for group_name,group_df in groups:
    f_se = group_df['age'].agg(['max','min','mean'])
    print('{}组的最大年龄是{},最小年龄是{},平均年龄是{}'.format(group_name,f_se[0],f_se[1],f_se[2]))
#注意:自定义的函数名字在传入agg()函数中时不需要转换成字符串。

观察上面的代码,可以发现在使用agg()函数时,我们可以将多个统计函数一起放到一个agg()函数中。

🚩并且需要注意的是,如果是统计函数是pandas提供的,我们只需将函数的名字以字符串的形势存储到列表中即可,例如:将max()改成'max'。

✨效果
在这里插入图片描述
这样不仅简化了我们的代码,在添加和删减统计函数的时候我们只需更改agg()函数中list就可以了。

它的好处还不止这些,比如现在又有新的需求,要计算年龄的最大值和最小值的差值。但是,pandas并没有提供这样统计函数,所以就需要我们进行自己定义一个统计函数:

def peak_range(df):
    """
        返回数值范围
    """
    return df.max() - df.min()

现在我们看一下自己定义的统计函数,如何使用

groups = df.groupby('国家')
def peak_range(df):
    """
        返回数值范围
    """
    return df.max() - df.min()
for group_name,group_df in groups:
    f_se = group_df['年龄'].agg(['max','min','mean',peak_range])
    print(f'{group_name}组的最大年龄是{f_se[0]},最小年龄是{f_se[1]},平均年龄是{f_se[2]},最大值减去最小值{f_se[3]}')


对于数据的分组统计处理,整理到这,有问题加我qq:2024810652

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐