【Python学习笔记】数据分组和数据透视表
2019-08-23 本文已影响0人
清梦载星河
镇楼图(图片源自unsplash)
一、数据分组
数据分组就是根据一个或多个键(可以是函数、数组或dataframe列名)将数据分为若干组,然后对分组后的数据分别进行汇总计算,并将汇总计算后的结果进行合并,被用作汇总计算的函数被称为聚合函数。
相关函数:
- DataFrame.groupby(self, by=None, axis=0, level=None, as_index=True, sort=True, group_keys=True, squeeze=False, observed=False, **kwargs)
1.1 准备数据
import numpy as np
import pandas as pd
rng = np.random.RandomState(0)
df = pd.DataFrame({'key':['A','B','C','A','B','C'],
'data1':range(6),
'data2':rng.randint(0,10,6)})
准备数据
1.2 设置分割的键
1.2.1 将列名、列表、数组、Series或索引作为分组键
# exp1 : 按照列key分组,之后分组求和
df.groupby('key').sum()
pic1.2.1(1)
# exp2 : 将列表作为分组键,之后分组求和
df.groupby(['key','data1']).sum()
pic1.2.1(2)
1.2.2 用字典或Series将索引映射到分组名称
dff = df.set_index('key')
mapping = {'A':'Apple','B':'BC','C':'BC'}
print(dff)
print('=====================')
print(dff.groupby(mapping).sum())
pic1.2.2
1.2.3 任意Python函数
dff = df.set_index('key')
mapping = {'A':'Apple','B':'BC','C':'BC'}
print(dff)
print('=====================')
print(dff.groupby(str.lower).sum())
pic1.2.3
1.2.4 多个有效键构成的列表
dff = df.set_index('key')
mapping = {'A':'Apple','B':'BC','C':'BC'}
print(dff)
print('=====================')
print(dff.groupby([str.lower,mapping]).sum())
pic1.2.4
1.3 Groupby对象的基本操作
1.3.1 聚合函数的基本操作
(类似1.1.2)
1.3.2 按列取值
Groupby对象和DataFrame对象一样,也支持按列取值,并返回一个修改过的Groupby对象。
# 不同key下data1的总和
df.groupby('key')['data1'].sum()
pic1.3.2
1.3.3 按组迭代
Groupby对象支持直接按组进行迭代,返回的每一组都是Series或DataFrame。
for (key,group) in df.groupby('key'):
print("{0} shape={1}".format(key,group.shape))
pic1.3.3
1.3.4 调用方法
Groupby对象可调用任意DataFrame或Series的方法。例如describe()
df.groupby('key').describe()
pic1.3.4
1.4 Groupby的进阶操作
1.4.1 累计:aggregate()
使用aggregate()方法能一次使用多个聚合函数。
#累计
df.groupby('key').aggregate([min,np.median,max])
pic1.4.1
1.4.2 过滤:filter()
过滤操作可以让你按照分组的属性丢弃若干数据。
# 过滤,仅保存标准差大于4的分组
print(df)
print("========================")
print(df.groupby('key').std())
print("========================")
print(df.groupby('key').filter(lambda x : x['data2'].std()>4))
pic1.4.2
1.4.3 转换:transfrom()
数据经过转换后,其形状与原来的数据是一样的。
# 转换,每一组的样本数据减去各组的均值
print(df)
print("======================")
print(df.groupby('key').transform(lambda x: x-x.mean()))
pic1.4.3
1.4.4 应用:apply()
apply()方法能让我们可以在每个组上应用任意方法。
# 转换,将第一列数据以第二列的和为基数进行标准化
print(df)
print("======================")
def norm_by_data2(x):
x['data1'] /= x['data2'].sum()
return x
print(df.groupby('key').apply(norm_by_data2))
pic1.4.4
二、数据透视表
数据透视表实现的功能与数据分组表相类似但又不同,数据分组是在一维(行)方向上不断拆分,而数据透视表是在行、列方向上同时拆分。
数据透视表将每一列数据作为输入,输出将数据不断细分成多个维度累计信息的二维数据表。
2.1 准备数据
#coding:utf-8
%matplotlib inline
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# 准备数据
titanic = sns.load_dataset('titanic')
titanic.head()
pic2.1
2.2 简单使用
#简单使用,查看生还者中性别和船舱等级的关系
titanic.pivot_table('survived',index='sex',columns='class')
# 等同以下groupby语句,先按照性别和船舱等级分组,
# 然后选中其中的生还者,再应用均值,最后使用unstack()将行索引转列索引
titanic.groupby(['sex','class'])['survived'].aggregate('mean').unstack()
pic2.2
2.3 数据透视表的语法
2.3.1 DataFrame.pivot_table()
#Pandas 0.25.1版本
DataFrame.pivot_table(self, values=None,
index=None, columns=None,
aggfunc='mean', fill_value=None,
margins=False, dropna=True,
margins_name='All', observed=False)
- values : 要做数据透视表的数据,即上面的'survived'
- index : 数据透视表中的行索引
- columns : 数据透视表中的列索引
- aggfunc : 设置累计函数类型,默认是均值(mean()),可以将字典作为参数传入。
- margins : 显示总数,默认不显示
- margins_name : 设置总数名,默认为 All
- fill_value : 对数据透视表中的缺失值进行填充
2.3.2 多级数据透视表
与Groupby类似,数据透视表中的分组也可以通过各种参数指定多个等级。例如,将年龄加入为第三个维度,并使用pd.cut()将年龄分段。
# 多级数据透视表,将年龄纳入参考数据,并用pd.cut()将年龄分段
age = pd.cut(titanic['age'],[0,18,80])
titanic.pivot_table(values='survived',
index=['sex',age],
columns='class')
pic2.3.2
2.3.3 其他数据透视表选项
- aggfunc参数
# aggfunc参数
titanic.pivot_table(index='sex',
columns='class',
aggfunc={'survived':sum,'fare':'mean'})
pic2.3.3(1)
此处省略了values参数,因为当我们为aggfunc指定了映射关系的时候,待透视的数值就已经确定了。
- margins和margins_name参数
# margin参数
titanic.pivot_table('survived',
index='sex',
columns='class',
margins=True,
margins_name='Total')
pic2.3.3(2)
margins用于设置总数的显示,margins_name用于设置总数的名称。