Pandas(七)--分组、合并和连接
目录
分组groupby()
创建DataFrame对象
创建分组对象
遍历分组数据
应用聚合函数
组的转换操作
组的数据过滤操作
合并merge()
1) 使用on参数合并
2) 使用how参数合并
连接concat()
行方向连接
列方向连接
append()
分组groupby()
在 Pandas 中,要完成数据的分组操作,需要使用 groupby() 函数,它和 SQL 的GROUP BY
操作非常相似。 在划分出来的组(group)上应用一些统计函数,从而达到数据分析的目的,比如对分组数据进行聚合、转换,或者过滤。这个过程主要包含以下三步:
- 拆分(Spliting):表示对数据进行分组;
- 应用(Applying):对分组数据应用聚合函数,进行相应计算;
- 合并(Combining):最后汇总计算结果。
创建DataFrame对象
首先我们创建一个 DataFrame 对象,下面数据描述了某班学生,计算机选修课的考试成绩:
- import pandas as pd
- import numpy as np
- data = {'Name': ['John', 'Helen', 'Sona', 'Ella'],
- 'score': [82, 98, 91, 87],
- 'option_course': ['C#','Python','Java','C']}
- df = pd.DataFrame(data)
- print(df)
输出结果:
Name score option_course 0 John 82 C# 1 Helen 98 Python 2 Sona 91 Java 3 Ella 87 C
创建分组对象
使用 groupby() 可以沿着任意轴分组。您可以把分组时指定的键(key)作为每组的组名,方法如下所示:
- df.groupby("key")
- df.groupby("key",axis=1)
- df.groupby(["key1","key2"])
# 生成分组groupby对象
df.groupby('score') # 为一个分组对象
#查看分组结果
print(df.groupby('score').groups)输出结果:
{82: Int64Index([0], dtype='int64'),
87: Int64Index([3], dtype='int64'),
91: Int64Index([2], dtype='int64'),
98: Int64Index([1], dtype='int64')}# 对多个列标签进行分组
#查看分组
print(df.groupby(['Name','score']).groups)输出结果:
{('Ella', 87): Int64Index([3], dtype='int64'),
('Helen', 98): Int64Index([1], dtype='int64'),
('John', 82): Int64Index([0], dtype='int64'),
('Sona', 91): Int64Index([2], dtype='int64')}#通过 get_group() 方法可以选择组内的具体数据项:
#根据score来分组
grouped=df.groupby('score')
#根据对应组的数据值,选择一个组
print(grouped.get_group(91))输出结果:Name score option_course
2 Sona 91 Java
遍历分组数据
通过以下方法来遍历分组数据,groupby 对象的组名称与 score 中的的元素值一一对应:
#分组
grouped=df.groupby('score')
for label, option_course in grouped:#其中key代表分组后字典的键,也就是scoreprint(label)#字典对应的值选修的科目print(option_course)输出结果:
82Name score option_course
0 John 82 C#
87Name score option_course
3 Ella 87 C
91Name score option_course
2 Sona 91 Java
98Name score option_course
1 Helen 98 Python
应用聚合函数
当您在创建 groupby 对象时,通过 agg() 函数可以对分组对象应用多个聚合函数:
grouped=df.groupby('name')
#应用一个聚合函数求均值
print(grouped['score']).agg(np.mean)输出结果:
name
Ella 87
Helen 98
John 82
Sona 91
Name: score, dtype: int64也可以一次性应有多个聚合函数,示例如下:
print(grouped['score'].agg([np.size, np.mean, np.std]))输出结果:size mean std
name
Ella 1 87 NaN
Helen 1 98 NaN
John 1 82 NaN
Sona 1 91 NaN
组的转换操作
在组的行或列上可以执行转换操作,最终会返回一个与组大小相同的索引对象。示例如下:
- import pandas as pd
- import numpy as np
- df = pd.DataFrame({'种类':['水果','水果','水果','蔬菜','蔬菜','肉类','肉类'],
- '产地':['朝鲜','中国','缅甸','中国','菲律宾','韩国','中国'],
- '水果':['橘子','苹果','哈密瓜','番茄','椰子','鱼肉','牛肉'],
- '数量':[3,5,5,3,2,15,9],
- '价格':[2,5,12,3,4,18,20]})
#分组求均值,水果、蔬菜、肉类
#对可执行计算的数值列求均值
print(df.groupby('种类').transform(np.mean))输出结果:数量 价格
0 4.333333 6.333333
1 4.333333 6.333333
2 4.333333 6.333333
3 2.500000 3.500000
4 2.500000 3.500000
5 12.000000 19.000000
6 12.000000 19.000000#transform()直接应用demean,实现去均值操作
demean = lambda arr:arr-arr.mean()
print(df.groupby('种类').transform(demean))输出结果:数量 价格
0 -1.333333 -4.333333
1 0.666667 -1.333333
2 0.666667 5.666667
3 0.500000 -0.500000
4 -0.500000 0.500000
5 3.000000 -1.000000
6 -3.000000 1.000000## 自定义函数,返回分组的前n行数据
def get_rows(df,n):#从1到n行的所有列return df.iloc[:n,:]
#分组后的组名作为行索引
print(df.groupby('种类').apply(get_rows,n=1))输出结果:种类 产地 水果 数量 价格
种类
水果 0 水果 朝鲜 橘子 3 2
肉类 5 肉类 韩国 鱼肉 15 18
蔬菜 3 蔬菜 中国 番茄 3 3
组的数据过滤操作
通过 filter() 函数可以实现数据的筛选,该函数根据定义的条件过滤数据并返回一个新的数据集。
下面,筛选出种类大于2的水果:
- #定义lambda函数来筛选数据
- print (df.groupby('种类').filter(lambda x: len(x) >= 2))
输出结果:
种类 产地 水果 数量 价格 0 水果 朝鲜 橘子 3 2 1 水果 中国 苹果 5 5 2 水果 缅甸 哈密瓜 5 12
合并merge()
Pandas 提供的 merge() 函数能够进行高效的合并操作,这与 SQL 关系型数据库的 MERGE 用法非常相似。其将两个 DataFrame 数据表按照指定的规则进行连接,最后拼成一个新的 DataFrame 数据表。
merge() 函数的语法格式如下:
pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None,left_index=False, right_index=False, sort=True,suffixes=('_x', '_y'), copy=True)
参数说明,如下表所示:
参数名称 | 说明 |
---|---|
left/right | 两个不同的 DataFrame 对象。 |
on | 指定用于连接的键(即列标签的名字),该键必须同时存在于左右两个 DataFrame 中,如果没有指定,并且其他参数也未指定, 那么将会以两个 DataFrame 的列名交集做为连接键。 |
left_on | 指定左侧 DataFrame 中作连接键的列名。该参数在左、右列标签名不相同,但表达的含义相同时非常有用。 |
right_on | 指定右侧 DataFrame 中作连接键的列名。 |
left_index | 布尔参数,默认为 False。如果为 True 则使用左侧 DataFrame 的行索引作为连接键,若 DataFrame 具有多层索引(MultiIndex),则层的数量必须与连接键的数量相等。 |
right_index | 布尔参数,默认为 False。如果为 True 则使用左侧 DataFrame 的行索引作为连接键。 |
how | 要执行的合并类型,从 {'left', 'right', 'outer', 'inner'} 中取值,默认为“inner”内连接。 |
sort | 布尔值参数,默认为True,它会将合并后的数据进行排序;若设置为 False,则按照 how 给定的参数值进行排序。 |
suffixes | 字符串组成的元组。当左右 DataFrame 存在相同列名时,通过该参数可以在相同的列名后附加后缀名,默认为('_x','_y')。 |
copy | 默认为 True,表示对数据进行复制。 |
注意:Pandas 库的 merge() 支持各种内外连接,与其相似的还有 join() 函数(默认为左连接)。
下面创建两个不同的 DataFrame,然后对它们进行合并操作:
import pandas as pd
left = pd.DataFrame({'id':[1,2,3,4],'Name': ['Smith', 'Maiki', 'Hunter', 'Hilen'],'subject_id':['sub1','sub2','sub4','sub6']})right = pd.DataFrame({'id':[1,2,3,4],'Name': ['William', 'Albert', 'Tony', 'Allen'],'subject_id':['sub2','sub4','sub3','sub6']})
print (left)
print (right)
输出如下:
id Name subject_id 0 1 Smith sub1 1 2 Maiki sub2 2 3 Hunter sub4 3 4 Hilen sub6id Name subject_id 0 1 William sub2 1 2 Albert sub4 2 3 Tony sub3 3 4 Allen sub6
1) 使用on参数合并
通过 on 参数指定一个连接键,然后对上述 DataFrame 进行合并操作:
#通过on参数指定合并的键
print(pd.merge(left,right,on='id'))输出结果:id Name_x subject_id_x Name_y subject_id_y
0 1 Smith sub1 William sub2
1 2 Maiki sub2 Albert sub4
2 3 Hunter sub4 Tony sub3
3 4 Hilen sub6 Allen sub6
在多个键上进行合并操作
下面示例,指定多个键来合并上述两个 DataFrame 对象:
print(pd.merge(left,right,on=['id','subject_id']))输出结果:id Name_x subject_id Name_y
0 4 Hilen sub6 Mike
2) 使用how参数合并
通过how
参数可以确定 DataFrame 中要包含哪些键,如果在左表、右表都不存的键,那么合并后该键对应的值为 NaN。为了便于大家学习,我们将 how 参数和与其等价的 SQL 语句做了总结:
Merge方法 | 等效 SQL | 描述 |
---|---|---|
left | LEFT OUTER JOIN | 使用左侧对象的key |
right | RIGHT OUTER JOIN | 使用右侧对象的key |
outer | FULL OUTER JOIN | 使用左右两侧所有key的并集 |
inner | INNER JOIN | 使用左右两侧key的交集 |
1) left join
#以left侧的subject_id为键
print(pd.merge(left,right,on='subject_id',how="left"))输出结果:id_x Name_x subject_id id_y Name_y
0 1 Smith sub1 NaN NaN
1 2 Maiki sub2 1.0 Bill
2 3 Hunter sub4 2.0 Lucy
3 4 Hilen sub6 4.0 Mike
2) right join#以right侧的subject_id为键
print(pd.merge(left,right,on='subject_id',how="right"))输出结果:id_x Name_x subject_id id_y Name_y
0 2.0 Maiki sub2 1 Bill
1 3.0 Hunter sub4 2 Lucy
2 4.0 Hilen sub6 4 Mike
3 NaN NaN sub3 3 Jack3) outer join(并集)
#求出两个subject_id的并集,并作为键
print(pd.merge(left,right,on='subject_id',how="outer"))输出结果:id_x Name_x subject_id id_y Name_y
0 1.0 Smith sub1 NaN NaN
1 2.0 Maiki sub2 1.0 Bill
2 3.0 Hunter sub4 2.0 Lucy
3 4.0 Hilen sub6 4.0 Mike
4 NaN NaN sub3 3.0 Jack4) inner join(交集)
#求出两个subject_id的交集,并将结果作为键
print(pd.merge(left,right,on='subject_id',how="inner"))输出结果:id_x Name_x subject_id id_y Name_y
0 2 Maiki sub2 1 Bill
1 3 Hunter sub4 2 Lucy
2 4 Hilen sub6 4 Mike
注意:当 a 与 b 进行内连操作时 a.join(b) 不等于 b.join(a)。
连接concat()
Pandas 通过 concat() 函数能够将 Series 与 DataFrame 对象组合在一起,函数的语法格式如下:
pd.concat(objs,axis=0,join='outer',join_axes=None,ignore_index=False)
参数说明如下所示:
参数名称 | 说明 |
---|---|
objs | 一个序列或者是Series、DataFrame对象。 |
axis | 表示在哪个轴方向上(行或者列)进行连接操作,默认 axis=0 表示行方向。 |
join | 指定连接方式,取值为{"inner","outer"},默认为 outer 表示取并集,inner代表取交集。 |
ignore_index | 布尔值参数,默认为 False,如果为 True,表示不在连接的轴上使用索引。 |
join_axes | 表示索引对象的列表。 |
concat() 函数用于沿某个特定的轴执行连接操作。下面让我们创建不同的对象,并对其进行连接。
- import pandas as pd
- a= pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],
- 'B': ['B0', 'B1', 'B2', 'B3'],
- 'C': ['C0', 'C1', 'C2', 'C3'],
- 'D': ['D0', 'D1', 'D2', 'D3']},
- index=[0, 1, 2, 3])
- b= pd.DataFrame({'A': ['A4', 'A5', 'A6', 'A7'],
- 'B': ['B4', 'B5', 'B6', 'B7'],
- 'C': ['C4', 'C5', 'C6', 'C7'],
- 'D': ['D4', 'D5', 'D6', 'D7']
- index=[2,3,4,5]})
行方向连接
#连接a与b
print(pd.concat([a,b]))输出结果:A B C D
0 A0 B0 C0 D0
1 A1 B1 C1 D1
2 A2 B2 C2 D2
3 A3 B3 C3 D3
2 A4 B4 C4 D4
3 A5 B5 C5 D5
4 A6 B6 C6 D6
5 A7 B7 C7 D7
如果想把指定的键与 DataFrame 对象连接,可以使用 keys 参数来实现。如下所示:
#连接a与b,并给a,b连接一个指定的键
print(pd.concat([a,b],keys=['x','y']))输出结果:A B C D
x 0 A0 B0 C0 D01 A1 B1 C1 D12 A2 B2 C2 D23 A3 B3 C3 D3
y 2 A4 B4 C4 D13 A5 B5 C5 D24 A6 B6 C6 D55 A7 B7 C7 D6
上述示中,可以看出行索引 index 存在重复使用的现象,如果想让输出的行索引遵循依次递增的规则,那么需要将 ignore_index 设置为 True。注意:此时的索引顺序被改变了,而且键 keys 指定的键也被覆盖了。
#连接a与b,设置 ignore_index 等于 True
print(pd.concat([a,b],keys=['x','y'],ignore_index=True))输出结果:A B C D
0 A0 B0 C0 D0
1 A1 B1 C1 D1
2 A2 B2 C2 D2
3 A3 B3 C3 D3
4 A4 B4 C4 D1
5 A5 B5 C5 D2
6 A6 B6 C6 D5
7 A7 B7 C7 D6
列方向连接
如果想要沿着 axis=1 添加两个对象,那么将会追加新的列。
#沿着 axis=1,连接a与b
print(pd.concat([a,b],axis=1))输出结果:A B C D A B C D
0 A0 B0 C0 D0 NaN NaN NaN NaN
1 A1 B1 C1 D1 NaN NaN NaN NaN
2 A2 B2 C2 D2 A4 B4 C4 D4
3 A3 B3 C3 D3 A5 B5 C5 D5
4 NaN NaN NaN NaN A6 B6 C6 D6
5 NaN NaN NaN NaN A7 B7 C7 D7
append()
如果要连接 Series 和 DataFrame 对象,有一个最方便、快捷的方法,那就是 append() 方法。该方法沿着 axis=0 (行方向)进行操作。
#沿着 axis=0,使用 apppend()方法连接a与b
print(a.append(b))输出结果:A B C D
0 A0 B0 C0 D0
1 A1 B1 C1 D1
2 A2 B2 C2 D2
3 A3 B3 C3 D3
2 A4 B4 C4 D4
3 A5 B5 C5 D5
4 A6 B6 C6 D6
5 A7 B7 C7 D7
Pandas(七)--分组、合并和连接相关推荐
- Python 之 Pandas (七)merge合并
代码: import pandas as pd# merging two df by key/keys # simple example left = pd.DataFrame({'key': ['K ...
- Pandas简明教程:九、表的合并、连接、拼接(数据聚合基础)
真实场景中常会遇到多种信息放在不同的表里的情况,此时我们就需要将这些表格的信息整合到一起.这种操作可以极大地减轻我们手动粘数据的工作,从而达到事半功倍的效果. 由于本篇要举的例子较多,因此直接采用官网 ...
- Python数据分析pandas之数据拼接与连接
Python数据分析pandas之数据拼接与连接 数据拼接处理 数据拼接处理指的是numpy.pandas里对数据的拼接.连接.合并等多种方法的概称.有时我们处理的数据会分很多步骤,而中间或者最终的结 ...
- 数据科学 IPython 笔记本 7.10 组合数据集:合并和连接
7.10 组合数据集:合并和连接 原文:Combining Datasets: Merge and Join 译者:飞龙 协议:CC BY-NC-SA 4.0 本节是<Python 数据科学手册 ...
- series 合并pandas_在python中pandas的series合并方法
如下所示: In [3]: import pandas as pd In [4]: a = pd.Series([1,2,3]) In [5]: b = pd.Series([2,3,4]) In [ ...
- Python常见数据处理技术——数据的概览与清洗、多表合并与连接、数据的汇总
目录 一.数据的概览与清洗 1.数值类型的判断和转换 2.冗余数据的判断和处理 3.缺失数据的判断与处理 二.多表合并与连接 1.合并函数concat 2.连接函数merge 三.数据的汇总 1.数据 ...
- Pandas快速入门之第三节使用pandas去重、合并、已经统计出现次数
前言: 本节主要参考的连接有, https://blog.csdn.net/brucewong0516/article/details/82707492 本节主要介绍如何使用pandas去重.合并.以 ...
- pandas高级处理-合并
pandas高级处理-合并 如果你的数据由多张表组成,那么有时候需要将不同的内容合并在一起分析 1 pd.concat实现数据合并 pd.concat([data1, data2], axis=1) ...
- 【Python基础】一文搞定pandas的数据合并
作者:来源于读者投稿 出品:Python数据之道 一文搞定pandas的数据合并 在实际处理数据业务需求中,我们经常会遇到这样的需求:将多个表连接起来再进行数据的处理和分析,类似SQL中的连接查询功能 ...
- Python数据分析pandas之分组统计透视表
Python数据分析pandas之分组统计透视表 数据聚合统计 Padans里的聚合统计即是应用分组的方法对数据框进行聚合统计,常见的有min(最小).max(最大).avg(平均值).sum(求和) ...
最新文章
- Lidar与IMU标定代码实战:lidar_align
- 世界物联网大会IOT
- VTK:图表之ColorVertexLabels
- Arduino总结一
- 疫情下的远程办公:理解Linux虚拟网络设备之tun/tap
- .7-Vue源码之AST(3)
- unity项目对音效的优化处理
- 硬件检测软件---AIDA64
- 计算机组成原理——存储器(一)
- 将个人文件夹挂载到服务器上,通过 WebDAV 将服务器全部或某个文件夹挂载到电脑上当网络硬盘 | 很文博客...
- CUDA 编程学习
- IBM发表未来5年5项科技预测 3D全息手机或现世
- C语言Matrix编程题——[Recursion]D. Liang 8.1 Computing factorials
- 如何实现在线直播源码的美颜功能——接入美颜SDK
- overleaf模板导入后中文无法识别问题解决方案
- MegaCli安装及使用
- dotnet 使用 Crossgen2 对 DLL 进行 ReadyToRun 提升启动性能
- _tmain与main,winMain,wmain收藏
- E. Add Modulo 10(规律)
- screen ruler屏幕电子尺源码C# 手机与windows