美文网首页Python可以做的那些事!码农的世界我爱编程
利用Python进行数据分析(十五)之分组级运算

利用Python进行数据分析(十五)之分组级运算

作者: BrainZou | 来源:发表于2018-04-22 23:51 被阅读16次

    分组级运算和转换

    聚合只是分组运算的一种,本节将介绍transform和apply方法,它们将能执行更多的分组运算。
    假设我们想为一个DataFrame添加一个用于存放索引分组平均值的列,按照之前的做法是:

    #先构建一个DataFrame
    import numpy as np
    import pandas as pd
    from pandas import Series,DataFrame
    data = {"data1":np.random.randn(5),"data2":np.random.randn(5),"key1":["a","a","b","b","a"],"key2":["one","two","one","two","one"]}
    df = DataFrame(data,columns =['data1','data2','key1','key2' ])
    df
    
    #通过groupby分组求平均组成新列。
    k1_means = df.groupby("key1").mean().add_prefix("mean_")
    k1_means 
    
    #再合并
    pd.merge(df,k1_means,left_on='key1',right_index = True)
    

    然而transform则是将函数应用到各个分组。
    df.groupby("key1").transform(np.mean)


    如果想要得到从各组中减去平均值。即距平化函数处理。我们先写出这个函数,然后应用这个函数到各个分组:
    def demean(arr):
        return arr-arr.mean()
    demeaned = df.groupby("key1").transform(demean)
    

    apply:一般性的“拆分-应用-合并”

    跟aggregate一样,transform也是一个有着严格条件的特殊函数:传入的函数只能产生两种结果.要么产生一个可以广播的标量值(如np.mean),要么产生一个相同大小的结果数组.最一般化的GroupBy方法是apply.本节剩余部分将重点讲解.apply会将待处理的对象拆分成多个片段,然后对齐片段调用传入的函数,最后尝试将各片段组合到一起。
    所以对比下transform和apply的区别:
    transform是对每组的数据分别处理后应用到每个数据。
    而apply则是分组后比如四组,对四个小组分别应用函数,然后数据组合在一起。而不会覆盖到每个数据。
    比如取出每组的data1的值最大的列:(sort_index现已改为sort_values)


    分位数和桶分析

    前面章节说过将数据拆分成多块(cut和qcut),将这些与groupby结合,即可实现对数据的桶或分位数分析。来看:

    #将df装入长度相等的桶中(labels=False则分组信息就默认用0123编号代替)
    factor = pd.cut(df.data1,4)
    
    #定义一个函数返回分组的最小值,最大值,个数和平均值
    def get_stats(group):
        return{'min':group.min(),'max':group.max(),'count':group.count(),'mean':group.mean()}
    #cut返回的Factor对象可直接用于groupby。即按找cut分组。
    grouped = df.data1.groupby(factor)
    #对分组后的数据应用函数,返回各个分组的信息。
    grouped.apply(get_stats).unstack()
    

    透视表和交叉表

    透视表根据一个或多个键对数据进行聚合.并根据行和列上的分组键将数据分配到各个矩形区域中.在Python和pandas中.可以通过本章所介绍的groupby功能以及(能够利用层次化索引的)重塑运算制作透视表。DataFrame有一个pivot_table方法,此外还有一个顶级的pandas.pivot_ table函数.除能为groupby提供便利之外,pivot_ table还可以
    添加分项小计(也叫做margins)。

    #取data1数据平均值(pivot_table默认),按行key1,列key2显示,margins添加分组统计(平均值)
    #注意是index和columns 不再是rows和cols
    df.pivot_table(['data1','data2'],index=['key1'],columns='key2',margins=True)
    

    注意看0.458889是(1.970981 - 0.297157 - 0.297157)/3得来的,因为有两个(a,one)。
    默认是平均值,使用其他的传给aggfunc参数即可,如aggfunc=len。


    privot_table的参数

    交叉表:crosstab

    交叉表(cross-tabulation,简称crosstab)是一种用于计算分组频率的特殊透视表。下面这个范例数据很典型,取自交叉表的Wikipedia页:


    如果想根据性别和用手习惯统计汇总,虽然可以用pivot_table实现,但是用pandas.crosstab函数更方便:


    crosstab的前两个参数可以是数组、Series或数组列表。再比如对小费数据集:

    pd.crosstab([tips.time, tips.day],tips.smoker, margins=True)
    

    总结

    继续介绍了数组聚合分组运算,重点介绍了transform和apply方法以及分位数和桶分析与groupby结合,以及一定情况下使用透视表和交叉表更为方便的显示。

    微信公众号:BrainZou
    欢迎关注,一起学习。

    相关文章

      网友评论

        本文标题:利用Python进行数据分析(十五)之分组级运算

        本文链接:https://www.haomeiwen.com/subject/fzrclftx.html