6-1 聚合统计和可视化

1.1 描述统计

分组对象如同df.describe(),也支持.describe(),用来对数据的总体进行描述:

# 描述统计
df.groupby('team').describe()
# 由于列过多,我们进行转置
df.groupby('team').describe().T

1.2 统计函数

对分组对象直接使用统计函数,对分组内的所有数据进行此计算,最终以DataFrame形式显示数据。

# 各组平均数
grouped.mean()

1.3 聚合方法agg()

分组对象的方法.aggregate()简写为.agg()。它的作用是将分组后的对象给定统计方法,也支持按字段分别给定不同的统计方法。

# 所有列使用一个计算方法
df.groupby('team').aggregate(sum)
df.groupby('team').agg(sum)
grouped.agg(np.size)
grouped['Q1'].agg(np.mean)

使用它主要是为了实现一个字段使用多种统计方法,不同字段使用不同方法:

# 每个字段使用多个计算方法
grouped[['Q1','Q3']].agg([np.sum, np.mean, np.std])

不同列使用不同计算方法,且一个列用多个计算方法:

df.groupby('team').agg({'Q1': ['min', 'max'], 'Q2': 'sum'})

类似于我们之前学过的增加新列的方法df.assign(),agg()可以指定新列的名字:

# 指定列名,列表是为原列和方法
df.groupby('team').Q1.agg(Mean='mean', Sum='sum')
df.groupby('team').agg(Mean=('Q1', 'mean'), Sum=('Q2', 'sum'))
df.groupby('team').agg(
    Q1_max=pd.NamedAgg(column='Q1', aggfunc='max'),        
    Q2_min=pd.NamedAgg(column='Q2', aggfunc='min')
    )

如果列名不是有效的Python变量格式,则可以用以下方法:

df.groupby('team').agg(**{
    '1_max':pd.NamedAgg(column='Q1', aggfunc='max')})

统计方法可以使用函数。在使用函数时,分别传入每个分组后的子DataFrame,会按子DataFrame把这组的所有列组成的序列传到函数里进行计算,最终返回一个固定值。

# 聚合结果使用函数
# lambda/函数,所有方法都可以用
def max_min(x):    
    return x.max() - x.min()
# 定义函数
df.groupby('team').Q1.agg(Mean='mean',          
                          Sum='sum',          
                          Diff=lambda x: x.max() - x.min(),          
                          Max_min=max_min          
                          )
如果对全列使用同一函数,直接写函数名即可:
# 调用函数
df.groupby('team').agg(max_min)

1.4 时序重采样方法resample()

针对时间序列数据,resample()将分组后的时间索引按周期进行聚合统计。

idx = pd.date_range('1/1/2020', periods=100, freq='T')
df2 = pd.DataFrame(data={'a':[0, 1]*50, 'b':1},
                   index=idx)

索引为一个时序数据,按下来,我们按a列进行分组,然后按每20分钟(由于1分钟是一个周期T,我们传入20T)对b进行求和计算:

# 每20分钟聚合一次
df2.groupby('a').resample('20T').sum()

# 三个周期一聚合(一分钟一个周期)
df.groupby('a').resample('3T').sum()
# 30秒一分组
df.groupby('a').resample('30S').sum()
# 每月
df.groupby('a').resample('M').sum()
# 以右边时间点为标识
df.groupby('a').resample('3T', closed='right').sum()

1.5 组内头尾值

在一个组内,如果希望取第一个值和最后一个值,可以使用以下方法。当然,定义第一个和最后一个是你需要事先完成的工作。

# 每组第一个
df.groupby('team').first()

# 每组最后一个
df.groupby('team').last()

1.6 组内分位数

我们经常使用中位数,它是分位数的一个特殊情形,为二分位。如果在分组中需要看指定分位数据,可以使用.quantile()来实现。

# 二分位数,即中位数
df.groupby('team').median() # 同下
df.groupby('team').quantile()
df.groupby('team').quantile(0.5)

1.7 组内差值

和DataFrame的diff()一样,分组对象的diff()方法会在组内进行前后数据的差值计算,并以原DataFrame形状返回数据:

# grouped为全数字列,计算在组内的前后差值
grouped.diff()

2 数据分箱

数据分箱(data binning,也称为离散组合或数据分桶)是一种数据预处理技术,它将原始数据分成几个小区间,即bin(小箱子),是一种量子化的形式。数据分箱可以最大限度减小观察误差的影响。落入给定区间的原始数据值被代表该区间的值(通常是中心值)替换。然后将其替换为针对该区间计算的常规值。这具有平滑输入数据的作用,并且在小数据集的情况下还可以减少过拟合。

Pandas主要基于以两个函数实现连续数据的离散化处理。

pandas.cut:根据指定分界点对连续数据进行分箱处理。
pandas.qcut:根据指定区间数量对连续数据进行等宽分箱处理。所谓等宽,指的是每个区间中的数据量是相同的。

2.1 定界分箱pd.cut()

# 将Q1成绩换60分及以上、60分以下进行分类
pd.cut(df.Q1, bins=[0, 60, 100])

将分箱结果应用到groupby分组中:
# Series使用
df.Q1.groupby(pd.cut(df.Q1, bins=[0, 60, 100])).count()

# DataFrame使用
df.groupby(pd.cut(df.Q1, bins=[0, 60, 100])).count()
# 不显示区间,使用数字作为每个箱子的标签,形式如0,1,2,n等
pd.cut(df.Q1, bins=[0, 60, 100],labels=False)
# 指定标签名
pd.cut(df.Q1, bins=[0, 60, 100],labels=['不及格','及格',])
# 包含最低部分
pd.cut(df.Q1, bins=[0, 60, 100], include_lowest=True)
# 是否为右闭区间,下例为[89, 100)
pd.cut(df.Q1, bins=[0, 89, 100], right=False)

2.2 等宽分箱pd.qcut()

pd.qcut()可以指定所分区间的数量,Pandas会自动进行分箱:

# 按Q1成绩分为两组
pd.qcut(df.Q1,q=2)
# 查看分组区间
pd.qcut(df.Q1,q=2).unique()

应用到分组中:

# Series使用
df.Q1.groupby(pd.qcut(df.Q1,q=2)).count()

# DataFrame使用
df.groupby(pd.qcut(df.Q1,q=2)).max()
pd.qcut(range(5), 4)
pd.qcut(range(5), 4,labels=False)
# 指定标签名
pd.qcut(range(5), 3,labels=["good", "medium", "bad"])
# 返回箱子标签 
array([1. ,51.5, 98.]))
pd.qcut(df.Q1, q=2, retbins=True)
# 分箱位小数位数
pd.qcut(df.Q1, q=2, precision=3)
排名分3个层次
pd.qcut(df.Q1.rank(method='first'), 3)

2.6 分组可视化

数据分组对象也支持plot(),不过它以分组对象中每个DataFrame或Series为对象,绘制出所有分组的图形。默认情况下,它绘制的是折线图

# 分组,设置索引为name
grouped = df.set_index('name').groupby('team')
# 绘制图形
grouped.plot()

还可以通过plot.x()或者plot(kind='x')的形式调用其他形状的图形,比如:

plot.line:折线图
plot.pie:饼图
plot.bar:柱状图
plot.hist:直方图
plot.box:箱形图
plot.area:面积图
plot.scatter:散点图
plot.hexbin:六边形分箱图

2.2 直方图hist()

组对象的hist()可以绘制出每个分组的直方图矩阵,每个矩阵为一个分组:

# 绘制直方图
grouped.hist()

2.3 箱线图boxplot()

分组的boxplot()方法绘制出每个组的箱线图。箱线图展示了各个字段的最大值、最小值、分位数等信息,为我们展示了数据的大体形象,代码如下。

# 分组箱线图
grouped.boxplot(figsize=(15,12))

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值