分组键可以有很多形式,且类型不必相同:
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. hibernate的拦截器和监听器

    拦截器(Intercept):顾名思义,拦截操作,也就是在Hibernate做出动作之前会调用的方法.如果你有需要在Hibernate操作数据库之前想要做的操作,就需要用到这个东西了. 监听器(Lis ...

  2. Mac中的brew

    最近要研究字体识别tesseract,才了解到brew,惭愧惭愧. 1.brew是一个软件包管理工具,类似于centos下的yum或者ubuntu下的apt-get,非常方便,免去了自己手动编译安装的 ...

  3. 由hbase.client.scanner.caching参数引发的血案(转)

    转自:http://blog.csdn.net/rzhzhz/article/details/7536285 环境描述 Hadoop 0.20.203.0Hbase 0.90.3Hive 0.80.1 ...

  4. 六、SpringBoot配置@ConfigurationProperties与@Value区别

    1.@Value的使用 三种用法 // ${key} 从环境变量.配置文件中取值 @Value("${person.last-name}") private String last ...

  5. oracle 数据恢复

    闪回表删除之前 flashback table t1 to before drop; 如果彻底删除表此方法无效 若要彻底删除表,则使用语句:drop table <table_name> ...

  6. 区间第k大的几种解法

    区间第K大问题,变化包括带修改和不带修改,强制在线和允许离线 修改主要是单点修改,我们前面也只讨论这种情况. 接下来我们从编程复杂度和时空复杂度来讨论几种做法. 1.整体二分(编程复杂度:低-中,时间 ...

  7. 【HDOJ6581】Vacation(模拟)

    题意:有标号从0到n的n+1辆车,每辆车离终点的距离为s[i],车长为l[i],速度为v[i],规定不能超车,问何时所有车都能过终点线 n<=1e5,保证 思路: #include<bit ...

  8. <Jmeter入门不放弃>之<3.两种常见录制脚本的方法>

    关于录制,我想表达的是,并不要以为他很低端,解决需求才是王道,大家这里参考学习的时候,我就不在这里配截图了,因为需要你打开工具根据文档自己去找,才有印象,大家一定要启动JMeter!跟着理解操作 录制 ...

  9. Python每日一题 008

    题目 基于多线程的网络爬虫项目,爬取该站点http://www.tvtv.hk 的电视剧收视率排行榜 分析 robots.txt User-agent: Yisouspider Disallow: / ...

  10. (转)Spring Boot干货系列:(三)启动原理解析

    转:http://tengj.top/2017/03/09/springboot3/ 前言 前面几章我们见识了SpringBoot为我们做的自动配置,确实方便快捷,但是对于新手来说,如果不大懂Spri ...