pandas数据分组groupby()和统计函数agg()的使用

数据分组

使用 groupby() 方法进行分组
group.size()查看分组后每组的数量
group.groups 查看分组情况
group.get_group(\'名字\') 根据分组后的名字选择分组数据

准备数据

# 一个Series其实就是一条数据,Series方法的第一个参数是data,第二个参数是index(索引),如果没有传值会使用默认值(0-N)
# index参数是我们自定义的索引值,注意:参数值的个数一定要相同。
# 在创建Series时数据并不一定要是列表,也可以将一个字典传进去。
from pandas import Series, DataFrame

# 使用字典创建
index_list = [\'001\', \'002\', \'003\', \'004\', \'005\', \'006\', \'007\', \'008\', \'009\', \'010\']
name_list = [\'李白\', \'王昭君\', \'诸葛亮\', \'狄仁杰\', \'孙尚香\', \'妲己\', \'周瑜\', \'张飞\', \'王昭君\', \'大乔\']
age_list = [25, 28, 27, 25, 30, 29, 25, 32, 28, 26]
gender_list = [\'F\', \'M\', \'F\', \'F\', \'M\', \'M\', \'F\', \'F\', \'M\', \'M\']
salary_list = [\'10k\', \'12.5k\', \'20k\', \'14k\', \'12k\', \'17k\', \'18k\', \'21k\', \'22k\', \'21.5k\']
marital_list = [\'NO\', \'NO\', \'YES\', \'YES\', \'NO\', \'NO\', \'NO\', \'YES\', \'NO\', \'YES\']
dic = {
 \'姓名\': Series(data=name_list, index=index_list),
 \'年龄\': Series(data=age_list, index=index_list),
 \'薪资\': Series(data=salary_list, index=index_list),
 \'性别\': Series(data=gender_list, index=index_list),
 \'婚姻状况\': Series(data=marital_list, index=index_list)
}
df = DataFrame(dic)

# 写入csv,path_or_buf为写入文本文件
df.to_csv(path_or_buf=\'./People.csv\', encoding=\'utf_8_sig\')
print(\'end\')

上面代码会在当前目录下生成一个 People.csv 文件

import pandas as pd
df = pd.read_csv(\'./People.csv\')
df.head()

pandas数据分组groupby()和统计函数agg()的使用

# 根据 \'性别列\' 进行分组, 得到的是一个分组后的对象
groups = df.groupby(\'性别\')
print(groups)
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x000002953DAEBC88>

size()

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

print(groups.size())
性别
F 5
M 5
dtype: int64

可以只对一列数据进行分组, 只保留想要的数据

例如: 通过性别, 只对年龄进行分组

group = df[\'年龄\'].groupby(df[\'性别\'])
# 查看分组
print(group.groups)
# 根据分组后的名字选择分组
print(group.get_group(\'F\'))
{\'F\': Int64Index([0, 2, 3, 6, 7], dtype=\'int64\'), \'M\': Int64Index([1, 4, 5, 8, 9], dtype=\'int64\')}
0 25
2 27
3 25
6 25
7 32
Name: 年龄, dtype: int64

代码df[\'年龄\'].groupby(df[\'性别\'])的逻辑是:取出df中\’年龄\’列数据,并且对该列数据根据df[‘性别\’]列数据进行分组操作
这个代码也可写成df.groupby(df[\'性别\'])[\'年龄\'], 他的逻辑是: 将df数据通过df[‘性别\’]进行分组,然后再取出分组后的\’年龄\’列数据。两种写法达到的效果是一样的
group.groups的结果是一个字典,字典的key是分组后每个组的名字,对应的值是分组后的数据,此方法方便我们产看分组的情况
group.get_group(\'F\')这个方法可以根据具体分组的名字获取,每个组的数据

 对分组进行遍历

import pandas as pd
df = pd.read_csv(\'./People.csv\')
groups = df.groupby(\'性别\')
# print(groups)
for group_name,group_df in groups:
 print(\'分组的名称:\', group_name, \'分组的数据\', group_df.shape)
 print(\'-\'*10)

分组的名称: F 分组的数据 (5, 6)
———-
分组的名称: M 分组的数据 (5, 6)
———-

– 将分组后的对象groups进行遍历,可以获取到group_name每个组的名字,group_df每个组的数据

import pandas as pd
df = pd.read_csv(\'./People.csv\')
groups = df.groupby(\'性别\')
for group_name,group_df in groups:
 f_mean = group_df[\'年龄\'].mean()
 f_max = group_df[\'年龄\'].max()
 f_min = group_df[\'年龄\'].min()
 print(\'{}组的最大年龄是{},最小年龄是{},平均年龄是{}\'.format(group_name,f_max,f_min,f_mean))

F组的最大年龄是32,最小年龄是25,平均年龄是26.8
M组的最大年龄是30,最小年龄是26,平均年龄是28.2

按多列进行分组

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

注意: 列表中列名的顺序, 确定了先按XXXX列分组, 然后在按照YYYY列分组, 不同的顺序产生的分组名字是不同的

df = pd.read_csv(\'./People.csv\')
group=df.groupby([\'性别\', \'婚姻状况\'])
df1 = group.size()
print(df1)

性别 婚姻状况
F  NO   2
  YES   3
M  NO   4
  YES   1
dtype: int64

group.size()返回的结果中发现索引值是多层的, 所以对于多索引值的获取, 只需要从外往里一层一层的取就可以啦, 就像我们睡觉之前,需要先脱外衣再脱掉内衣是一样的

size = df1[\'F\'][ \'NO\']
print(size)

2

pandas 常用统计函数

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

对分组后的数据进行统计 agg()

import pandas as pd
df = pd.read_csv(\'./People.csv\')
groups = df.groupby(\'性别\')
for group_name,group_df in groups:
  f_se = group_df[\'年龄\'].agg([\'max\',\'min\',\'mean\'])
  print(\'{}组的最大年龄是{},最小年龄是{},平均年龄是{}\'.format(group_name,f_se[0],f_se[1],f_se[2]))

F组的最大年龄是32.0,最小年龄是25.0,平均年龄是26.8
M组的最大年龄是30.0,最小年龄是26.0,平均年龄是28.2

在使用 agg() 函数时, 我们可以将多个统计函数一起放在一个 agg() 函数中
如果是统计函数是pandas 提供的, 只需要将函数名字以字符串的形式存储到列表中即可
例如: 将 max() 改成 ‘max\’

自定义统计函数

当使用自定义的统计函数时
先创建统计函数

# 自定义的统计函数
def my_peak_range(df):
  \"\"\"
  返回最大值与最小之间的范围
  \"\"\"
  return df.max() - df.min()

# 使用
for group_name,group_df in groups:
  f_se = group_df[\'年龄\'].agg([\'max\',\'min\',\'mean\',my_peak_range])
  print(f_se[0],f_se[1],f_se[3])
32.0 25.0 7.0
30.0 26.0 4.0

注意: 自定义函数名字传入agg() 函数时, 不需要转换成字符串

补充: 在这个数据中, 性别是什么的人总年龄最高

import pandas as pd
df = pd.read_csv(\'./People.csv\')
groups = df.groupby(\'性别\')
gende=groups.sum().sort_values(by=\'年龄\',ascending=False).index.to_list()[0]
\"\"\"
这行代码, 先按性别进行分组, 然后吧每组中的数据求和得到总的年龄, 在按照年龄排序
再取出index,最后使用to_list()转换为列表,取出第一个数据
\"\"\"

print(gende)

M

开始按照性别分组, 组量太少, 数据也比较少, 本来准备算薪资总数, 但是单位忘记换了, 就这样吧

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容