什么是聚合?
- 在SQL中我们经常使用 GROUP BY 将某个字段,按不同的取值进行分组, 在pandas中也有groupby函数
- 分组之后,每组都会有至少1条数据, 将这些数据进一步处理返回单个值的过程就是聚合,比如 分组之后计算算术平均值, 或者分组之后计算频数,都属于聚合
单变量分组聚合
以年份分组,查看寿命的平均值
df.groupby('year')['lifeExp'].mean()
- groupby 语句会针对每个不同年份重复上述过程,并把所有结果放入一个DataFrame中返回
- mean函数不是唯一的聚合函数, Pandas内置了许多方法, 都可以与groupby语句搭配使用
Pandas内置的聚合方法
可以和groupby一起使用的方法和函数:
Pandas方法 | Numpy函数 | 说明 |
count | np.count_nonzero | 频率统计(不包含NaN值) |
size | 频率统计(包含NaN值) | |
mean | np.mean | 求平均值 |
std | np.std | 标准差 |
min | np.min | 最小值 |
quantile() | np.percentile() | 分位数 |
max | np.max | 求最大值 |
sum | np.sum | 求和 |
var | np.var | 方差 |
describe | 计数、平均值、标准差,最小值、分位数、最大值 | |
first | 返回第一行 | |
last | 返回最后一行 | |
nth | 返回第N行(Python从0开始计数) |
聚合函数
Numpy库和pandas数据类型是一样的,也可以使用Numpy库中的mean()函数来计算平均值:
调用不是pandas自带的方法时,需要使用agg或者aggregate回调
df.groupby('year')['lifeExp'].agg(np.mean)
自定义函数
def my_mean(values):
"""
计算平均值
@params:传过来的数据
@return:返回平均值
"""
n = len(values)
sum = 0
for value in values:
sum += value
return (sum / n)
df.groupby('year')['lifeExp'].agg(my_mean)
效果一样:
- 自定义函数中只有一个参数values, 但传入该函数中的数据是一组值, 需要对values进行迭代才能取出每一个值
自定义函数可以有多个参数, 第一个参数接受来自DataFrame分组这之后的值, 其余参数可自定义
agg同时传入多个函数
按年计算lifeExp 的非零个数,平均值和标准差
把函数放在列表内传入agg函数:
df.groupby('year').lifeExp.agg([np.count_nonzero,np.mean,np.std])
分组之后,可以对多个字段用不同的方式聚合
对年龄用自定义函数求平均值,对人数求中位数,对gdp求标准差
df.groupby('year').agg({'lifeExp':my_mean,'pop':'median','gdpPercap':'std'})
转换
- transform 转换,需要把DataFrame中的值传递给一个函数, 而后由该函数"转换"数据。
- aggregate(聚合) 返回单个聚合值,但transform 不会减少数据量
df.groupby('year')['lifeExp'].transform(my_mean)
没有减少数据,DataFrameGroupBy对象的transform方法
过滤
- 使用groupby方法还可以过滤数据,调用filter 方法,传入一个返回布尔值的函数,返回False的数据会被过滤掉
原数据:
tips = pd.read_csv('data/tips.csv')
# 查看用餐人数
tips['size'].value_counts()
以size分组,过滤掉size字段数量小于30的分组
tips_filtered = tips.groupby('size').filter(lambda x:x['size'].count()>30)