分组键可以有很多形式,且类型不必相同:
1、列表或数组,其长度与待分组的轴一样
2、表示DataFrame某个列名的值
3、字典或Series,给出待分组轴上的值与分组名之间的对应关系
4、函数,用于处理轴索引或索引中的各个标签
 
1、分组键为Series

 df=DataFrame({'key1':['a','a','b','b','a'],
'key2':['one','two','one','two','one'],
'data1':np.random.randn(5),
'data2':np.random.randn(5)}) df
Out[6]:
data1 data2 key1 key2
0 -0.814074 1.244593 a one
1 -1.203203 -0.199076 a two
2 0.846649 1.136826 b one
3 -1.700835 1.822935 b two
4 1.190682 -2.001369 a one

按照key1进行分组,并计算data1列的平均值,这里使用:访问data1,并根据key1调用groupby:

 grouped=df['data1'].groupby(df['key1'])
grouped
Out[6]: <pandas.core.groupby.SeriesGroupBy object at 0x000000000ADEEC18>

变量grouped是一个GroupBy对象。实际上还没有进行任何计算,只是含有一些有关分组键df['key1']的中间数据。换句话说,该对象已经有了接下来对个分组执行运算所需的一切信息。

 #调用GroupBy的mean方法计算分组平均值
grouped.mean()
Out[8]:
key1
a -0.275532
b -0.427093
Name: data1, dtype: float64
可以看出,数据(Series)根据分组键进行了聚合,产生了一个新的Series,其索引为key1列中的唯一值。之所以结果中索引的名称为key1,是因为原始DataFrame的列df['key1']就叫这个名字。
一次传入多个数组

 #一次传入多个数组,使用列表方式[]
means=df['data1'].groupby([df['key1'],df['key2']]).mean() means
Out[11]:
key1 key2
a one 0.188304
two -1.203203
b one 0.846649
two -1.700835
Name: data1, dtype: float64 #分组后得到的Series具有一个层次化索引
means.unstack()
Out[12]:
key2 one two
key1
a 0.188304 -1.203203
b 0.846649 -1.700835
 
2、分组键是数组
上面的示例中,分组键均为Series,实际上,分组键可以是任何长度适当的数组

 states=np.array(['Ohio','California','California','Ohio','Ohio'])

 years=np.array([2005,2005,2006,2005,2006])

 df['data1'].groupby([states,years]).mean()
Out[15]:
California 2005 -1.203203
2006 0.846649
Ohio 2005 -1.257454
2006 1.190682
Name: data1, dtype: float64
 
3、列名做分组键
此外还可以将列名(可以是字符串、数字或其他Python对象)作为分组键:

 df.groupby('key1').mean()
Out[16]:
data1 data2
key1
a -0.275532 -0.318617
b -0.427093 1.479880 df.groupby(['key1','key2']).mean()
Out[17]:
data1 data2
key1 key2
a one 0.188304 -0.378388
two -1.203203 -0.199076
b one 0.846649 1.136826
two -1.700835 1.822935
可以注意到,在执行df.groupby('key1').mean()时,结果中没有key2列。这是因为df['key2']不是数值数据(俗称“麻烦列”),所以从结果中排除了。默认情况下,所有数值列都会被聚合
GroupBy的size方法,它可以返回一个含有分组大小的Series:

 df.groupby(['key1','key2']).size()
Out[18]:
key1 key2
a one 2
two 1
b one 1
two 1
dtype: int64
对分组进行迭代
GroupBy对象支持迭代,可以产生一组二元元组(由分组名和数据块组成)。

 for name,group in df.groupby('key1'):
print(name)
print(group) a
data1 data2 key1 key2
0 -0.814074 1.244593 a one
1 -1.203203 -0.199076 a two
4 1.190682 -2.001369 a one
b
data1 data2 key1 key2
2 0.846649 1.136826 b one
3 -1.700835 1.822935 b two

多重键,元组的第一个元素将会是由键值组成的元组

 for (k1,k2),group in df.groupby(['key1','key2']):
print(k1,k2)
print(group) a one
data1 data2 key1 key2
0 -0.814074 1.244593 a one
4 1.190682 -2.001369 a one
a two
data1 data2 key1 key2
1 -1.203203 -0.199076 a two
b one
data1 data2 key1 key2
2 0.846649 1.136826 b one
b two
data1 data2 key1 key2
3 -1.700835 1.822935 b two

可以对这些数据片段做任何操作,例如:将这些数据片段做成一个字典。

 pieces=dict(list(df.groupby('key1')))

 pieces
Out[24]:
{'a': data1 data2 key1 key2
0 -0.814074 1.244593 a one
1 -1.203203 -0.199076 a two
4 1.190682 -2.001369 a one, 'b': data1 data2 key1 key2
2 0.846649 1.136826 b one
3 -1.700835 1.822935 b two} pieces['b']
Out[25]:
data1 data2 key1 key2
2 0.846649 1.136826 b one
3 -1.700835 1.822935 b two

groupby默认是在axis=0上进行分组的,通过设置也可以在其他任何轴上进行分组。

 df.dtypes
Out[26]:
data1 float64
data2 float64
key1 object
key2 object
dtype: object #在axis=1分组
grouped=df.groupby(df.dtypes,axis=1)
dict(list(grouped))
Out[29]:
{dtype('float64'): data1 data2
0 -0.814074 1.244593
1 -1.203203 -0.199076
2 0.846649 1.136826
3 -1.700835 1.822935
4 1.190682 -2.001369, dtype('O'): key1 key2
0 a one
1 a two
2 b one
3 b two
4 a one}
选取一个或一组列
对于由DataFrame产生的GroupBy对象,如果用一个(单个字符串)或一组(字符串数组)列名对其进行索引,就能实现选取部分列进行聚合的目的。

 df.groupby('key1')['data1']
df.groupby('key1')[[data2']]
#上面的代码是下面代码的语法糖
df['data1'].groupby(df['key1'])
df[['data2']].groupby(df['key1'])
 #对部分列进行聚合
df.groupby(['key1','key2'])[['data2']].mean()
Out[32]:
data2
key1 key2
a one -0.378388
two -0.199076
b one 1.136826
two 1.822935

这样操作返回的对象是一个已分组的DataFrame(传入的是列表或数组)或已分组的Series(传入的是标量形式的单个列名):

 s_grouped=df.groupby(['key1','key2'])['data2']
s_grouped.mean()
Out[36]:
key1 key2
a one -0.378388
two -0.199076
b one 1.136826
two 1.822935
Name: data2, dtype: float64

4、通过字典或Series进行分组

 people=DataFrame(np.random.randn(5,5),
columns=['a','b','c','d','e'],
index=['Joe','Steve','Wes','Jim','Travis']) #将行索引为2,列索引名为'b','c'的数据赋值为NaN
people.ix[2:3,['b','c']]=np.nan
__main__:1: DeprecationWarning:
.ix is deprecated. Please use
.loc for label based indexing or
.iloc for positional indexing See the documentation here:
http://pandas.pydata.org/pandas-docs/stable/indexing.html#ix-indexer-is-deprecated people
Out[42]:
a b c d e
Joe 0.125621 -0.059778 0.437543 -1.583435 0.472849
Steve 0.855371 0.461129 -0.126290 0.146014 0.373913
Wes -2.106125 NaN NaN 0.895130 -1.547358
Jim 0.155206 0.202384 0.932044 -1.171872 -1.035313
Travis 0.875559 -0.161025 0.482190 1.593750 0.637874

假设已知列的分组关系,并希望根据分组计算列的总计:

 mapping={'a':'red','b':'red','c':'blue',
'd':'blue','e':'red','f':'orange'} #将mapping这个字典传给groupby
by_column=people.groupby(mapping,axis=1) by_column.sum()
Out[45]:
blue red
Joe -1.145892 0.538692
Steve 0.019724 1.690413
Wes 0.895130 -3.653483
Jim -0.239828 -0.677722
Travis 2.075939 1.352408
 
5、用Series做分组键
Series也有同样的功能,被看做一个固定大小的映射。用Series做分组键,pandas会检查Series以确保其索引跟分组轴是对齐的:

 map_series=Series(mapping)

 map_series
Out[48]:
a red
b red
c blue
d blue
e red
f orange
dtype: object people.groupby(map_series,axis=1).count()
Out[49]:
blue red
Joe 2 3
Steve 2 3
Wes 1 2
Jim 2 3
Travis 2 3
6、通过函数进行分组
任何被当做分组键的函数都会在各个索引值上被调用一次,其返回值就会被用作分组名称。

 people.groupby(len).sum()
Out[50]:
a b c d e
3 -1.825298 0.142606 1.369587 -1.860177 -2.109822
5 0.855371 0.461129 -0.126290 0.146014 0.373913
6 0.875559 -0.161025 0.482190 1.593750 0.637874

将函数和数组、列表、字典、Series混合使用也必是问题,因为任何东西最终都会被转换为数组:

 key_list=['one','one','one','two','two']
people.groupby([len,key_list]).min()
Out[53]:
a b c d e
3 one -2.106125 -0.059778 0.437543 -1.583435 -1.547358
two 0.155206 0.202384 0.932044 -1.171872 -1.035313
5 one 0.855371 0.461129 -0.126290 0.146014 0.373913
6 two 0.875559 -0.161025 0.482190 1.593750 0.637874
7、根据索引级别分组
层次化索引数据集最方便的地方在于能够根据索引级别进行聚合。

 columns=pd.MultiIndex.from_arrays([['US','US','US','JP','JP'],
[1,3,5,1,3]],names=['cty','tenor']) hier_df=DataFrame(np.random.randn(4,5),columns=columns) hier_df
Out[58]:
cty US JP
tenor 1 3 5 1 3
0 1.641749 2.434674 -0.546666 0.797418 0.530019
1 0.084086 0.309776 -0.322581 1.996448 -0.093791
2 1.387329 -0.200419 -0.182946 -0.811081 1.081501
3 -0.237261 0.288679 -0.057882 0.267184 0.907478 #通过level关键字传入级别编号或名称
hier_df.groupby(level='cty',axis=1).count()
Out[59]:
cty JP US
0 2 3
1 2 3
2 2 3
3 2 3

groupby 技术的更多相关文章

  1. pandas聚合和分组运算——GroupBy技术(1)

    数据聚合与分组运算——GroupBy技术(1),有需要的朋友可以参考下. pandas提供了一个灵活高效的groupby功能,它使你能以一种自然的方式对数据集进行切片.切块.摘要等操作.根据一个或多个 ...

  2. python库学习笔记——分组计算利器:pandas中的groupby技术

    最近处理数据需要分组计算,又用到了groupby函数,温故而知新. 分组运算的第一阶段,pandas 对象(无论是 Series.DataFrame 还是其他的)中的数据会根据你所提供的一个或多个键被 ...

  3. python groupby

    groupby() 将key函数作用于原循环器的各个元素.根据key函数结果,将拥有相同函数结果的元素分到一个新的循环器.每个新的循环器以函数返回结果为标签. 这就好像一群人的身高作为循环器.我们可以 ...

  4. pandas中的分组技术

    目录 1  分组操作 1.1  按照列进行分组 1.2  按照字典进行分组 1.3  根据函数进行分组 1.4  按照list组合 1.5  按照索引级别进行分组 2  分组运算 2.1  agg 2 ...

  5. 利用 groupby apply list 分组合并字符

    利用 groupby apply list 分组合并字符 因为需要对数据进行分组和合并字符,找到了以下方法. 有点类似 SQL 的 Group BY. import pandas as pd impo ...

  6. Python数据聚合和分组运算(1)-GroupBy Mechanics

    前言 Python的pandas包提供的数据聚合与分组运算功能很强大,也很灵活.<Python for Data Analysis>这本书第9章详细的介绍了这方面的用法,但是有些细节不常用 ...

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

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

  8. iBatis系列一

    XML iBatis可以使用xml来作为参数输入以及结果返回:这个功能的优势在于某些特定的场景:还有可以通过DOM方式来作为参数传递:但是这个方式应用的比较少,如果服务器是xml服务器可以采用这种方式 ...

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

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

随机推荐

  1. JS事件循环(Event Loop)机制

    前言 众所周知,为了与浏览器进行交互,Javascript是一门非阻塞单线程脚本语言. 为何单线程? 因为如果在DOM操作中,有两个线程一个添加节点,一个删除节点,浏览器并不知道以哪个为准,所以只能选 ...

  2. new做了些什么?

    new做了些什么? function People(name, age){ this.name = name; this.age = age; }; var xiaoming = new People ...

  3. SQL数据库—<4>SQL编程--简单学习

    数据类型:列的类型 变量定义:declare 变量名 类型名    变量名:以@开头 赋值和取值:    赋值:set/select 变量=值    取值:变量名例:declare @a varcha ...

  4. for循环(C语言型)流程

  5. 西里尔字 俄语 - Cyrillic

    https://zh.wikipedia.org/wiki/%E8%A5%BF%E9%87%8C%E5%B0%94%E5%AD%97%E6%AF%8D 其他编码[编辑] 其他适用西里尔字母的字符编码系 ...

  6. tomcat的server.xml配置

    <Host>标签 appBase属性:            1 这个目录下面的子目录将自动被部署为应用.           2 这个目录下面的.war文件将被自动解压缩并部署为应用 一 ...

  7. SCP-bzoj-1085

    项目编号:bzoj-1085 项目等级:Safe 项目描述: 戳这里 特殊收容措施: A*(上下界剪枝). 答案上界:15. 答案下界:当前步数+当前状态剩余步数估价. 这里我们简单地设计估价函数为当 ...

  8. Linux常用命令的使用方法

    Linux 命令大全 Linux 命令大全 1.文件管理 cat chattr chgrp chmod chown cksum cmp diff diffstat file find git gitv ...

  9. shell变量相关知识

    环境变量和普通变量 一.几个常用命令: 1. set : 输出所有变量,包含全局变量和局部变量 2. env : 只显示全局变量 3. declare : 输出所有的变量,函数,整数和已经导出的变量 ...

  10. 74HC AHCT LS LV ABT区别

    1. 含义 2. 74AHC 74AHCT 74LV 74LS 2.1 解释 AHC与AHCT均是先进的高速的CMOS器件,但是供电电压范围不同,输入的逻辑电平也不同. LV是低压版,当自身供电电压为 ...