前言

Python的pandas包提供的数据聚合与分组运算功能很强大,也很灵活。《Python for Data Analysis》这本书第9章详细的介绍了这方面的用法,但是有些细节不常用就容易忘记,遂打算把书中这部分内容总结在博客里,以便复习查看。根据书中的章节,这部分知识包括以下四部分:

1.GroupBy Mechanics(groupby技术)

2.Data Aggregation(数据聚合)

3.Group-wise Operation and Transformation(分组级运算和转换)

4.Pivot Tables and Cross-Tabulation(透视表和交叉表)

本文是第一部分,介绍groupby技术。

一、分组原理

核心:

1.不论分组键是数组、列表、字典、Series、函数,只要其与待分组变量的轴长度一致都可以传入groupby进行分组。

2.默认axis=0按行分组,可指定axis=1对列分组。

对数据进行分组操作的过程可以概括为:split-apply-combine三步:

1.按照键值(key)或者分组变量将数据分组。

2.对于每组应用我们的函数,这一步非常灵活,可以是python自带函数,可以是我们自己编写的函数。

3.将函数计算后的结果聚合。

图1:分组聚合原理(图片来自《Python for Data Analysis》page 252)

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

我们将key1当做我们的分组键值,对data1进行分组,再求每组的均值:

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

语法很简单,但是这里需要注意grouped的数据类型,它不在是一个数据框,而是一个GroupBy对象。

grouped

实际上,在这一步,我们并没有进行任何计算仅仅是创建用key1分组后创建了一个GroupBy对象,我们后面函数的任何操作都是基于这个对象的。

求均值:

grouped.mean()

刚刚我们只是用了key1进行了分组,我们也可以使用两个分组变量,并且通过unstack方法进行结果重塑:

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

means.unstack

以上我们的分组变量都是df内部的Series,实际上只要是和key1等长的数组也可以:

states = np.array(['Ohio', 'California', 'California', 'Ohio', 'Ohio'])
years = np.array([2005, 2005, 2006, 2005, 2006])
df['data1'].groupby([states, years]).mean()

二、对分组进行迭代

GroupBy对象支持迭代操作,会产生一个由分组变量名和数据块组成的二元元组:

for name, group in df.groupby('key1'):
print name
print group

如果分组变量有两个:

for (k1,k2), group in df.groupby(['key1','key2']):
print k1,k2
print group

我们可以将上面的结果转化为list或者dict,来看看结果是什么样的:

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

看不太清楚,我们来看看这个列表的第一个元素:

list(df.groupby(['key1','key2']))[0]

同样,我们也可以将结果转化为dict(字典):

dict(list(df.groupby(['key1','key2'])))

dict(list(df.groupby(['key1','key2'])))[('a','one')]

以上都是基于行进行分组,因为默认情况下groupby是在axis=0方向(行方向)进行分组,我们可以指定axis=1方向(列方向)进行分组:

grouped=df.groupby(df.dtypes,axis=1)
list(grouped)[0]

dict(list(grouped))

注意,

'''下面两段语句功能一样'''
df.groupby('key1')['data1']
df.data1.groupby(df.key1)

三、通过字典进行分组

people = pd.DataFrame(np.random.randn(5, 5),
columns=['a', 'b', 'c', 'd', 'e'],
index=['Joe', 'Steve', 'Wes', 'Jim', 'Travis'])
people.ix[2:3, ['b', 'c']] = np.nan # 添加缺失值
people

假如,我们想按列进行聚合,该怎么操作呢?

我们根据实际情况,对列名建立字典,然后将此字典传入groupby,切记指定axis=1,因为我们是对列进行分组聚合:

mapping = {'a': 'red', 'b': 'red', 'c': 'blue',
'd': 'blue', 'e': 'red', 'f' : 'orange'}
by_columns=people.groupby(mapping,axis=1)
by_columns.mean()

既然我们可以通过传入字典来对列进行分组,那么肯定也可以通过传入Series来对列进行分组了(Series中的index就相当字典中的key嘛):

map_series = pd.Series(mapping)
people.groupby(map_series,axis=1).count()

四、通过函数进行分组

刚刚我们分组时利用了dict和series建立映射,对于一些复杂的需求,我们可以直接对groupby函数传递函数名来进行分组,以刚才的people数据为例,如果我们想按行分组,分组的key是每个人名的字母长度,该怎么做呢?比较直接的想法是相对每个名字求长度,建立一个数组,然后将这个数组传入groupby,我们来试验一下:

l=[len(x) for x in people.index]
people.groupby(l).count()

方案可行,那么有没有更快捷更优美的方法呢?当然有啦,我们只需将len这个函数名传给groupby即可:

people.groupby(len).count()

除了传递函数,我们也可以将函数和dict,series,array一起使用,毕竟最后都会统统转化为数组:

key_list = ['one', 'one', 'one', 'two', 'two']
people.groupby([len, key_list]).min()

五、根据索引级别分组

刚刚我们的数据索引只有一级,当数据有多级索引时,可以通过level指定我们想要分组的索引,注意要使用axis=1表示按列:

columns = pd.MultiIndex.from_arrays([['Asian', 'Asian', 'Asian', 'America', 'America'],
['China','Japan','Singapore','United States','Canada']], names=['continent', 'country'])
hier_df = pd.DataFrame(np.random.randn(4, 5), columns=columns)
hier_df

我们按洲进行分组求和:

Python数据聚合和分组运算(1)-GroupBy Mechanics的更多相关文章

  1. Python 数据分析(二 本实验将学习利用 Python 数据聚合与分组运算,时间序列,金融与经济数据应用等相关知识

    Python 数据分析(二) 本实验将学习利用 Python 数据聚合与分组运算,时间序列,金融与经济数据应用等相关知识 第1节 groupby 技术 第2节 数据聚合 第3节 分组级运算和转换 第4 ...

  2. 【学习】数据聚合和分组运算【groupby】

    分组键可以有多种方式,且类型不必相同 列表或数组, 某长度与待分组的轴一样 表示DataFrame某个列名的值 字典或Series,给出待分组轴上的值与分组名之间的对应关系 函数用于处理轴索引或索引中 ...

  3. Python数据聚合和分组运算(2)-Data Aggregation

    在上一篇博客里我们讲解了在python里运用pandas对数据进行分组,这篇博客将接着讲解对分组后的数据进行聚合. 1.python 中经过优化的groupy方法  先读入本文要使用的数据集tips. ...

  4. 《python for data analysis》第九章,数据聚合与分组运算

    # -*- coding:utf-8 -*-# <python for data analysis>第九章# 数据聚合与分组运算import pandas as pdimport nump ...

  5. Python之数据聚合与分组运算

    Python之数据聚合与分组运算 1. 关系型数据库方便对数据进行连接.过滤.转换和聚合. 2. Hadley Wickham创建了用于表示分组运算术语"split-apply-combin ...

  6. Python 数据分析—第九章 数据聚合与分组运算

    打算从后往前来做笔记 第九章 数据聚合与分组运算 分组 #生成数据,五行四列 df = pd.DataFrame({'key1':['a','a','b','b','a'], 'key2':['one ...

  7. 《利用python进行数据分析》读书笔记--第九章 数据聚合与分组运算(一)

    http://www.cnblogs.com/batteryhp/p/5046450.html 对数据进行分组并对各组应用一个函数,是数据分析的重要环节.数据准备好之后,通常的任务就是计算分组统计或生 ...

  8. 利用python进行数据分析之数据聚合和分组运算

    对数据集进行分组并对各分组应用函数是数据分析中的重要环节. group by技术 pandas对象中的数据会根据你所提供的一个或多个键被拆分为多组,拆分操作是在对象的特定轴上执行的,然后将一个函数应用 ...

  9. 利用Python进行数据分析-Pandas(第六部分-数据聚合与分组运算)

    对数据集进行分组并对各组应用一个函数(无论是聚合还是转换),通常是数据分析工作中的重要环节.在将数据集加载.融合.准备好之后,通常是计算分组统计或生成透视表.pandas提供了一个灵活高效的group ...

随机推荐

  1. Altium Designer之多图纸设计

    Altium Designer的多图纸功能感觉比较方便:今天翻了下徐老师<Altium Designer 快速入门>里面关于多图纸设计的介绍,再参考了altium 网站的一些资料,算是摸熟 ...

  2. MyBatis3配置文件示例及解释

    转自:https://blog.csdn.net/tobylxy/article/details/84320694 1 <?xml version="1.0" encodin ...

  3. .NET 调用c++库注意事项

    很久没有更新了,主要还是因为自己懒吧,希望从今天开始坚持至少一周写一篇文章. 调用函数库是正常的,调用完成后,在使用EF进行数据更新时,将发生如下异常信息,而且几乎必现. 行库遇到了错误.此错误的地址 ...

  4. CE学习记录1

    主题 春节放假终于有空学习下怎么制作外挂啦......学习写外挂大概是我一开始学习计算机的动力吧....只是一直似懂非懂..看教学视频各种不明白为什么....也没有专门的时间学习下怎么写....春节有 ...

  5. dyld_decache&MesaSQLite

    [dyld_decache] Starting from iPhone OS 3.1, the individual libraries files supplied by the system ar ...

  6. C#支持的编码格式

    转自: http://www.java2s.com/Book/CSharp/0040__Essential-Types/Get_all_supported_encodings.htm using Sy ...

  7. 带你剖析WebGis的世界奥秘----Geojson数据加载(高级)(转)

    带你剖析WebGis的世界奥秘----Geojson数据加载(高级) 转:https://zxhtom.oschina.io/zxh/20160819.html  编程  java  2016/08/ ...

  8. python-memcached模块

    memcache memcache介绍 memcache概念 Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库 ...

  9. python 将字符串转化为可执行代码

    场景: 在一个遍历的的程序中,有一步需要调用函数,调用的方式是根据输入参数,从3个可供被调用的函数中,选择其中一个.所以写了一个dict={1:"function_a_name", ...

  10. oracle获取表和列的备注

    using System;using System.Collections.Generic;using System.Data;using System.Linq;using System.Runti ...