分组键可以有很多形式,且类型不必相同:
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. javascript基础六(事件对象)

    1.事件驱动     js控制页面的行为是由事件驱动的.          什么是事件?(怎么发生的)     事件就是js侦测到用户的操作或是页面上的一些行为       事件源(发生在谁身上)   ...

  2. 2019牛客暑期多校训练营(第三场)I Median

    题意:给出n-2的中位数序列b,b[i]代表原序列中(a[i],a[i+1],a[i+2])的中位数,求a. 解法:比赛的时候没做出来,赛后看题解的.解法跟网上各位大佬一样:首先要证明其实原序列a中的 ...

  3. VUE前端面试题

    什么是 mvvm? MVVM 是 Model-View-ViewModel 的缩写.mvvm 是一种设计思想.Model 层代表数据模型,也可以在 Model 中定义数据修改和操作的业务逻辑:View ...

  4. python 常用技巧 — 字典 (dictionary)

    目录: 1. python 相加字典所有的键值 (python sum all values in dictionary) 2. python 两个列表分别组成字典的键和值 (python two l ...

  5. 【杂】聊聊我的男神:Jordan Peterson

    这篇文章我打算聊聊我的男神Jordan Peterson(简称JP).如果还不太了解JP,那么下面两个链接是JP的背景介绍: [文字]Jordan Peterson From Wikipedia, t ...

  6. PHP chdir() 函数

    实例 改变当前的目录: <?php// Get current directoryecho getcwd() . "<br>"; // Change direct ...

  7. UNP学习 广播

    一.概述 虽然UDP支持各种形式的地址,但TCP只支持单播地址. 上图要点是: IPv4对多播的支持是可选的,而IPv6则时必须的. IPv6没有提供对广播的支持:当使用广播的IPv4应用程序一直到I ...

  8. C# GDI+简单绘图

    一.使用Pen画笔 Pen的主要属性有: Color(颜色),DashCap(短划线终点形状),DashStyle(虚线样式),EndCap(线尾形状), StartCap(线头形状),Width(粗 ...

  9. jenkins安装-配置

    jenkins安装-配置 注意: jenkins访问 用chrome浏览器 安装包下载:http://pkg.jenkins-ci.org/redhat/ (使用2.92版本的) 安装jdk: 1.8 ...

  10. js判断是否pc端

    function IsPC() { var userAgentInfo = navigator.userAgent; var Agents = ['Android', 'iPhone', 'Symbi ...