pandas数据分组、聚合和简单可视化操作和方法。
分组聚合操作
# Pandas分组聚合:数据的分组聚合操作
import pandas as pd
df = pd.read_excel("datasets/team.xlsx")
df.groupby(['team']).sum() # 分组、聚合[求和]操作
df.groupby(['team']).agg({'Q1':sum, 'Q2':max, 'Q3':min, 'Q4':'mean'}) # 应用不同的聚合计算方式
df.groupby(['team']).agg({'Q1':[sum,max, min], 'Q2':max, 'Q3':min, 'Q4':'mean'}) # 同一列应用多种聚合计算方法
# 分组过程,groupby按照指定字段对数据进行分组,生成分组器对象
df.groupby("team") # 单列分组
df.groupby(['team']) # 单列分组
df.groupby(['team', 'Q1']).sum() # 多列分组
# 分组对象的查看
group = df.groupby("team")
group.get_group('A') # 查看team为A的单个分组对象内容
# 分组依据也可传入函数,将数据分成多组【例如True和False两种】
def score(index):
score = df.loc[index]['Q1':'Q4'].mean()
if score >= 90:
return 'A'
elif score >= 80:
return 'B'
elif score >= 60:
return 'C'
else:
return 'D'
group = df.groupby(lambda x:score(x)) # 根据平均成绩分为四组
group['team'].count() # 各组数量
分组器
# 分组器Grouper,可以复用分组工作
df.groupby(pd.Grouper('team', sort=True), as_index=False).sum() # 分组字段不成为索引
df.groupby('team', sort=False).sum()
df.drop('name', axis=1) # 删除某列axis=1或者删除某行axis=0
分组对象查看
# 分组对象内容的查看,类似于字典的操作
df.groupby('team').groups # 全部数据,
df.groupby('team').groups.keys() # 分组名
df.groupby('team').groups.values() # 分组对象内容[行号]
df.groupby('team').get_group('A') # 选择某个分组数据
# indices返回一个字典
df.groupby('team').indices
# 迭代分组
for k,rf in df.groupby('team'):
print(tf)
apply/pipe/transform
# apply,返回函数处理后的DataFrame
df.set_index('name').groupby('team').apply(lambda x:x['Q1'].sort_values(ascending=False).head(3)) # 选出按照team分组后,各组Q1成绩排行前三的呢
# 管道方法pipe,
df.groupby('team').pipe(lambda x: x.max() + x.min())
# 同理,apply实现:
df.groupby('team').apply(lambda x: x.max() + x.min())
# transform,与agg类似,但返回与原数据相同形状的DataFrame
df.groupby('team').transform('sum')
df.groupby('team').ngroup() # 分组序号
df.groupby('team').nth(1)
df.bfill() # 使用后一个值填充当前缺失值
df.shift(2) #数据移位
# 时间序列
df2 = pd.DataFrame(data={'a':[0,1]*50, 'b':1},index=pd.date_range('1/1/2020', periods=100, freq='t'))
# 时序重采样
df2.resample('3T').groups
数据分箱(data binning),或离散组合或数据分桶
是一种数据预处理技术,将原数据分成几个小区间,是一种量化操作。
落入给定区间的原数据值被代表该区间的值替换。
作用:平滑输入数据,在小数据集的情况下还可以减少过拟合。
pandas使用两个函数:pd.cut(指定分界点分箱数据)/pd.qcut(指定分箱数量等分数据)
# 定界分箱pd.cut
# 为便于比较分箱结果和原数据,使用assign链式编程, 默认左开右闭合
df.assign(bin_r=pd.cut(df.Q1, bins=[0,60,100])) # 指定分界点
# 分箱结果和分组groupby集合,和正常的分组操作类似,将分箱结果看为临时的列数据
df.groupby(pd.cut(df.Q1, bins=[0,60,100])).count() # 分箱结果分组数量统计(DataFrame)
df.Q1.groupby(pd.cut(df.Q1, bins=[0,60,100])).count() # 分箱结果分组数量统计(Series)
# 自定义分箱标签ins=[0,60,100], labels=False)) # 数字作为标签
df.assign(bin_r=pd.cut(df.Q1, bins=[0,60,100], labels=['及格','不及格'])) # 自定义
df.assign(bin_r=pd.cut(df.Q1, bins=[0,60,100], right=False)) # 左闭右开
# 等宽分箱
df.assign(bin_r=pd.qcut(df.Q1, 4, precision=3)) # 等分成四个分箱
分组可视化,pandas提供的简单的与分组相关的可视化方法
# 基本的plot方法,默认折线图
df.set_index('name').groupby('team').plot()
结果:
team
A AxesSubplot(0.125,0.125;0.775x0.755)
B AxesSubplot(0.125,0.125;0.775x0.755)
C AxesSubplot(0.125,0.125;0.775x0.755)
D AxesSubplot(0.125,0.125;0.775x0.755)
E AxesSubplot(0.125,0.125;0.775x0.755)
dtype: object
图形结果:
df.set_index('name').groupby('team').hist() #直方图
df.set_index('name').groupby('team').boxplot() # 箱线图