pandas学习路线:
Python-Pandas{数据结构与基本功能
Python-Pandas{描述与统计功能}
Python-pandas{缺失值处理}
Python-pandas{文本数据处理}
Python-pandas{数据分组}
其实这种数据分组与SQL中的Group by语句的功能是一样的。
实际上,我们可以把 groupby 理解成一个分割(split),应用(apply),组合(combine)的过程
一个经典分割-应用-组合操作如下图所示,其中应用的是一个求和函数.
- 分割: 将 DataFrame按照指定的键分割成若干组
- 应用: 对每个组应用函数, 通常是累计,转换或过滤函数
- 组合: 将每一组的结果合并成一个输出组
数据分组
在数据处理中, 我们经常需要把某些特征的共同值进行累计分析.
例如有一列特征, 储存的是用户学历数据, 分为, 初中, 高中, 大学,我们经常做的一件事情是, 将初中的, 高中, 大学的都各自分为一组, 然后统计每一组中的不同统计量的值.
import numpy as np
import pandas as pd
data = {
'学历':['高中生', '大学生', '高中生', '高中生', '高中生', '大学生', '大学生','研究生','研究生','大学生'],
'测试成绩':[65, 67, 44, 58, 55, 77, 76,82,91,56], # 答题结果
'产品评分':[3,1,3,2,3,1,3,3,2,2] # 1: 差 2: 一般 :优秀
}
df = pd.DataFrame(data)
df # 数据是对我们的一款在线答题产品的测试数据
df.groupby('学历') # by 以----进行分组
'''
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x000002442FF883D0>
'''
# 看到返回结果,我们就知道groupby 其实是返回了一个对象
需要注意的是,这里的返回值不是一个 DataFrame 对象,而是一个 DataFrameGroupBy 对象。
你可以将它看成是一种特殊形式的 DataFrame,里面隐藏着若干组数据,但是在没有应用累计函数之前并不会真的计算。
可以通过遍历的方法, 将DataFrameGroupBy中的数据打印出来
for group_name,group_data in df.groupby('学历'):
print(group_name)
print("-------")
print(group_data)
print('---------分割线----------')
'''
大学生
-------
学历 测试成绩 产品评分
1 大学生 67 1
5 大学生 77 1
6 大学生 76 3
9 大学生 56 2
---------分割线----------
研究生
-------
学历 测试成绩 产品评分
7 研究生 82 3
8 研究生 91 2
---------分割线----------
高中生
-------
学历 测试成绩 产品评分
0 高中生 65 3
2 高中生 44 3
3 高中生 58 2
4 高中生 55 3
---------分割线----------
'''
# 我们也可以使用列表
a,b,c = list(df.groupby('学历'))
# 输出的结果为一样的
我们在应用累计函数之后, 就会完成真正的计算
df.groupby('学历').count()
df.groupby('学历').sum()
df.groupby('学历').mean()
筛选列
可以直接在groupby对象中选择列
df.groupby('学历')['产品评分'].mean()
'''
学历
大学生 1.75
研究生 2.50
高中生 2.75
Name: 产品评分, dtype: float64
'''
# 也可以统计后在选择列
df.groupby('学历').mean()['测试成绩']
'''
学历
大学生 69.0
研究生 86.5
高中生 55.5
Name: 测试成绩, dtype: float64
'''
# 也可以对数据中的一列进行分组, 通过数据中另外一列
df.产品评分
'''
0 3
1 1
2 3
3 2
4 3
5 1
6 3
7 3
8 2
9 2
Name: 产品评分, dtype: int64
'''
df.学历
df.产品评分.groupby(df.学历).mean()
'''
学历
大学生 1.75
研究生 2.50
高中生 2.75
Name: 产品评分, dtype: float64
'''
# 统计每一组数据的分类个数
df.groupby('学历')['产品评分'].value_counts()
df.groupby('学历')['产品评分'].value_counts().unstack() # 转换为二维数据
也可以使用describe()
方法查看统计数据
df.groupby('学历').describe()
# 统计每一组数据的分类个数
df.groupby('学历')['产品评分'].value_counts()
df.groupby('学历')['产品评分'].value_counts().unstack() # 转换为二维数据
高级方法
- 假如对于一列,我想要同时应用多个统计函数呢?
test = df.groupby('学历')
# agg 方法
test.agg('mean')
test.agg(['max','min','mean','sum','std'])
- 假如对于不同的列,我想要用不同的统计函数呢?
test.agg({"测试成绩":['min','max','mean'], "产品评分":['var','std','sum']})
- 应用自定义函数进行统计
# 提取每一组第二大分数
def f(x): # x代表了我们将来会传进来的每一组数据
return x['测试成绩'].sort_values(ascending=False).iloc[1]
# 应用自定义函数
df.groupby('学历').apply(f)