zoukankan      html  css  js  c++  java
  • python数据分析之:数据聚合与分组运算

    在数据库中,我们可以对数据进行分类,聚合运算。例如groupby操作。在pandas中同样也有类似的功能。通过这些聚合,分组操作,我们可以很容易的对数据进行转换,清洗,运算。比如如下图,首先通过不同的键值进行分类,然后对各个分类进行求和运算。

    我们来看实际的例子,首先生成一组数据如下

    df=DataFrame({'key1':['a','a','b','b','a'],'key2':['one','two','one','two','one'],'data1':np.random.randn(5),'data2':np.random.randn(5)})

          data1     data2 key1 key2

    0  0.426519  0.321085    a  one

    1  0.918215  0.418922    a  two

    2 -2.792968  0.629589    b  one

    3 -0.431760  0.231652    b  two

    4  0.570083 -0.799304    a  one

    然后针对data1列根据key1的值来进行分组

    groupd=df['data1'].groupby(df['key1'])

    得到groupd只是一个聚合的对象,我们可以在这个对象上进行各种运算。比如groupd.mean(), groupd.sum()分别代表平均数,求和。结果如下,生成了一个新的数据列,且列名还是key1

    key1

    a    0.146577

    b   -0.947097

    Name: data1, dtype: float64

    key1

    a    0.439730

    b   -1.894193

    Name: data1, dtype: float64

    groupby中还可以传递多个数组,比如

    groupd1=df['data1'].groupby([df['key1'],df['key2']]).sum()

    结果如下:通过key1列进行聚合后,在通过key2列对之前的数据再聚合然后求和。

    key1  key2

    a     one    -0.115901

          two    -0.030998

    b     one    -0.039265

          two     0.295743

    Name: data1, dtype: float64

    当然还可以将列名也用作分组键。

    df.groupby(df['key1']).mean()

             data1     data2

    key1                    

    a     0.381235  0.453622

    b    -0.179429 -0.880869

    df.groupby([df['key1'],df['key2']]).mean()

                  data1     data2

    key1 key2                    

    a    one   0.466122  0.328501

         two   0.211462  0.703865

    b    one   0.848630 -0.598706

         two  -1.207488 -1.163033

    通过上面的结果可以看到通过key1进行分组的时候key2列是不存在的,这是因为key2列不是整数数据。所以从结果中排除了。

    对元组进行迭代

    前面通过df.groupby(df[‘key1’])进行分组的时候,我们其实得到了两类分组,一种是a的分组,一种是b的分组。因为在key1列中只有这2个值,如果我们想分别访问这两组分组的数据,就需要用到迭代了。

        for group1,group2 in df.groupby(df['key1']):

            print group1,group2

    这样就分别得到了针对a,b的各自分组。

    a       data1     data2 key1 key2

    0 -0.973337  0.656690    a  one

    1  0.930285 -2.361232    a  two

    4 -0.195729 -0.717847    a  one

    b       data1     data2 key1 key2

    2 -0.167785 -0.907817    b  one

    3 -2.245887 -0.170275    b  two

    对于多列的分组:

        for group1,group2 in df.groupby([df['key1'],df['key2']]):

            print group1

            print group2

    结果如下,总共有4个分组。分别是(‘a’,’one’),(‘a’,’two’),(‘b’,’one’),(‘b’,’two’)

    ('a', 'one')

          data1     data2 key1 key2

    0 -0.430579 -0.810844    a  one

    4  0.481271 -0.998662    a  one

    ('a', 'two')

          data1     data2 key1 key2

    1 -0.114657  1.062592    a  two

    ('b', 'one')

          data1     data2 key1 key2

    2 -0.996202  0.661732    b  one

    ('b', 'two')

          data1    data2 key1 key2

    3  0.812372 -1.09057    b  two

    下面总结一下groupby的聚合运算的方法:

    apply:

    apply会将待处理的对象拆分成多个片段。然后将各片段调用传入的函数,最后尝试将各段组合在一起。来看下面的这个例子:

    def get_stats(group):

        return {'min':group.min(),'max':group.max(),'count':group.count(),'mean':group.mean()}

    def group_by_test():

        frame=DataFrame({'data1':np.random.randn(100),'data2':np.random.randn(100)})

        factor=pd.cut(frame.data1,4)

        print factor

    print frame.data2.groupby(factor).apply(get_stats)

    首先在group_by_test中,通过pd.cutframe进行4分位分隔。然后对各个分位进行聚合。最后通过apply函数对各个分组调用get_stats函数。这个函数的作用和下面的代码的作用是一样的。

    for g in frame.data2.groupbyby(facotr):

      get_stats(g)

    随机采样和排列:

    假设想要从一个大数据集中随机抽样样本进行分析工作。np.random.permutation(N)选取前k个元素其中N为完整数据的大小,K为期望的样本大小。下面举一个扑克牌的例子

    def draw(deck,n=5):

        return deck.take(np.random.permutation(len(deck))[:n])

    def group_by_test2():

        card_val=(range(1,11)+[10]*3)*4  #牌的序号 

        base_name=['A']+range(2,11)+['J','K','Q'] #牌名

        cards=[]

        suits=['H','S','C','D'] #花色:红桃(Hearts),黑桃(Spades),梅花(Clubs),方片(Diamonds)

        for suit in ['H','S','C','D']:

            cards.extend(str(num)+suit for num in base_name) #产生牌

        deck=Series(card_val,index=cards)

        get_suit=lambda card:card[-1] #根据牌名最后一个字符也就是花色进行分组。

    print deck.groupby(get_suit).apply(draw,n=2)

    运行结果:

    C  8C     8

       9C     9

    D  KD    10

       QD    10

    H  5H     5

       9H     9

    S  7S     7

       JS    10

    dtype: int64

  • 相关阅读:
    Windows常用命令的使用
    Windows网络命令的相关指令(1)
    HashMap源码解析
    Head First 设计模式【一、设计模式入门】
    软技能-代码之外的生存指南【职业篇】
    记第一个项目结束时的感想
    2019年总结
    深入理解计算机系统【五】-存储器层次结构
    深入理解计算机系统【四】-程序的机器级表示
    深入理解计算机系统【三】
  • 原文地址:https://www.cnblogs.com/zhanghongfeng/p/8745415.html
Copyright © 2011-2022 走看看