pandas-03-组合连接数据

采集的数据存储后通常会分为多个文件或数据库,如何将这些文件按需拼接,或按键进行连接十分重要。这节将介绍数据索引的复杂操作如分层索引,stack,unstack,seet_index,reset_index等帮助重构数据,数据的拼接如merge,join,concat,combine_first等帮助连接数据,以及数据透视表的使用。

目录

  • A. 分层索引
    • 1. 创建分层索引
      • A.1.1 Series分层索引
      • A.1.2 DataFrame分层索引
      • A.1.3 直接创建多层索引再重用它
    • 2. 分层索引的引用与属性
      • A.2.1 对分层Series的引用
      • A.2.1 分层DataFrame的层数判断
    • 3. 多层行列索引之间的转换
      • A.3.1 Series.unstack() DataFrame.stack() 用法
      • A.3.2 DataFrame.set_index 与 DataFrame.reset_index
      • A.3.3 索引轴更换顺序与排序
    • 4. 分层计算统计量
  • B. 组合与合并数据
    • 1. pd.merge() pd.join()使用键连接数据
      • B.1.1 根据Df的列(键)合成数据
      • B.1.2 根据Df的索引列合成数据
      • B.1.3 合成的集合选择方式(how参数)
      • B.1.4 合成时不作为键但列名相同的列(suffixes参数)
      • B.1.5 pd.merge参数总结(其他参数)
      • B.1.6 使用pd.join简化按索引列合并
    • 2. pd.concat()按轴方向串联数据
    • 3. df.combine_first()实现有重复索引的选择性拼接
  • C. 数据透视表
    • C.1 df.pivot
    • C.2 pd.melt

A. 分层索引

1. 创建分层索引

A.1.1 Series分层索引

  • 在创建Series时,使用嵌套列表的方式指定它的索引,就会生成分层索引的Series数组
  • 可以使用S.index.names 对多层索引命名
  • S.index 是一个多层索引对象MultiIndex,它的每一个元素是一个元组
data = pd.Series(np.random.uniform(size=9),index=[["a", "a", "a", "b", "b", "c", "c", "d", "d"],[1, 2, 3, 1, 3, 1, 2, 2, 3]],)
data.index.names = ['word','num']

在这里插入图片描述

A.1.2 DataFrame分层索引

  • 在创建DataFrame时,指定它的行和列都是用嵌套列表,就会生成分层索引的Df
  • 可以对行和列的分层索引命名 Df.index.name=[ ] ,Df.columns.names=[ ]
frame = pd.DataFrame(np.arange(12).reshape((4, 3)),index=[["a", "a", "b", "b"], [1, 2, 1, 2]],columns=[["Ohio", "Ohio", "Colorado"],["Green", "Red", "Green"]])
frame.index.names = ["key1", "key2"]
frame.columns.names = ["state", "color"]                             

在这里插入图片描述
在这里插入图片描述

A.1.3 直接创建多层索引再重用它

除了在创建Series和DataFrame时,通过嵌套列别指定所层索引的形式,还可以直接生成所层索引MultiIndex,这样可以重复使用这个索引。

pd.MultiIndex.from_arrays([["Ohio", "Ohio", "Colorado"],["Green", "Red", "Green"]],names=["state", "color"])

在这里插入图片描述

2. 分层索引的引用与属性

A.2.1 对分层Series的引用

A.3.1 可以看出Series分层索引与Df之间可以相互转换,所以使用对Df的引用方法可以实现对Series的引用。下面实例中data是前文的data
在这里插入图片描述

A.2.1 分层DataFrame的层数判断

Df.index.nlevels
Df.columns.nelvels

在这里插入图片描述

3. 多层行列索引之间的转换

A.3.1 Series.unstack() DataFrame.stack() 用法

每一次使用unstack相当于把行中最内层的索引放到列最内层中,比如原来行有a,b,c和1,2,3这两种索引,使用一次unstack会把内层的1,2,3这个索引放到行上,形成Df。
在这里插入图片描述
对于三层的行索引可以更清晰的看出,比如下面这个数据有a,b,c ;1,2,3;x,y,z三种,每一次使用unstack会把最内层的行索引放到最内层的列索引中。直到最后索引顺序变为x,y,z;1,2,3;a,b,c。

data_ = pd.Series(np.random.uniform(size=9),index=[["a", "a", "a", "b", "b", "c", "c", "d", "d"],[1, 2, 3, 1, 3, 1, 2, 2, 3],['x','y','x','y','x','y','x','y','x']])
data_.index.nlevels
data_.unstack()
data_.unstack().unstack()
data_.unstack().unstack().unstack()

在这里插入图片描述

  • 可以通过level指定要挪动的索引,可以使用整数位置或者索引标签名称,但是默认还是会放到列的最内侧。
    df.unstack(level=0)
    df.unstack(level=‘name1’)
  • 使用.stack方法后会默认将含有空值的行删除,使用dropna=Falese参数可以保留空值。
data = pd.DataFrame(np.arange(6).reshape((2, 3)),index=pd.Index(["Ohio", "Colorado"], name="state"),columns=pd.Index(["one", "two", "three"],name="number"))
result.unstack(level=0)
result.unstack(level="state")

在这里插入图片描述

s1 = pd.Series([0, 1, 2, 3], index=["a", "b", "c", "d"], dtype="Int64")
s2 = pd.Series([4, 5, 6], index=["c", "d", "e"], dtype="Int64")
data2 = pd.concat([s1, s2], keys=["one", "two"])data2.unstack()
data2.unstack().stack(dropna=False)

在这里插入图片描述

df = pd.DataFrame({"left": result, "right": result + 5},columns=pd.Index(["left", "right"], name="side"))
df
df.unstack(level="state")df.unstack(level="state").stack(level="side")

在这里插入图片描述

A.3.2 DataFrame.set_index 与 DataFrame.reset_index

  • 可以 选择把Df的某列或某几列作为多层索引Df.set_index([‘col1’,‘col2’])
  • 默认变成索引的列不再出现在列中,但是使用drop=False可以让成为索引的列仍然出现在行中
  • 将所有的索引都移动到列中Df.reset_index
frame = pd.DataFrame({"a": range(7), "b": range(7, 0, -1),"c": ["one", "one", "one", "two", "two","two", "two"],"d": [0, 1, 2, 0, 1, 2, 3]})
frame2 = frame.set_index(["c", "d"])
frame.set_index(["c", "d"], drop=False)
frame2.reset_index()                     

在这里插入图片描述

A.3.3 索引轴更换顺序与排序

Df.swaplevel('key1,key2']
Df.sort_index(level=1)
Df.sawplevel(0,1).sort_index(level=0)

在这里插入图片描述

4. 分层计算统计量

使用groupby

frame.groupby(level="key2").sum()
frame.groupby(level="color", axis="columns").sum()

在这里插入图片描述

B. 组合与合并数据

1. pd.merge() pd.join()使用键连接数据

将两个Df对象按照某列的对应关系,或者索引之间的对应关系合并成一张表,在关系型数据库中这种操作很常见。在pandas中使用merge或者join函数完成这种合并连接。下面详细介绍pd.merge()的详细用法。假设待连接的两个数组分别是df1,df2。

B.1.1 根据Df的列(键)合成数据

  • pd.merge(df1,df2) 不指定键名,将默认使用重复的列作为键连接两个数组
  • pd.merge(df1,df2,on=‘key’) ;on 参数需要是两个数组共有的列名,将以它为键进行合并
  • pd.merge(df1,df2,left_on=‘lkey’,right_on=‘rkey’) ;用于两个数组分别以不同的列名作为键合并
  • 也可以指定多个列为连接的键pd.merge(left, right, on=[“key1”, “key2”])
#data
df1 = pd.DataFrame({"key": ["b", "b", "a", "c", "a", "a", "b"],"data1": pd.Series(range(7), dtype="Int64")})
df2 = pd.DataFrame({"key": ["a", "b", "d"],"data2": pd.Series(range(3), dtype="Int64")})#pd.merge
pd.merge(df1, df2)
pd.merge(df1, df2, on="key")#left_on,right_on
df3 = pd.DataFrame({"lkey": ["b", "b", "a", "c", "a", "a", "b"],"data1": pd.Series(range(7), dtype="Int64")})
df4 = pd.DataFrame({"rkey": ["a", "b", "d"],"data2": pd.Series(range(3), dtype="Int64")})
pd.merge(df3, df4, left_on="lkey", right_on="rkey")                    #指定多个键,默认将取两个键都对应的在两个数组间的交集
left = pd.DataFrame({"key1": ["foo", "foo", "bar"],"key2": ["one", "two", "one"],"lval": pd.Series([1, 2, 3], dtype='Int64')})
right = pd.DataFrame({"key1": ["foo", "foo", "bar", "bar"],"key2": ["one", "one", "one", "two"],"rval": pd.Series([4, 5, 6, 7], dtype='Int64')})
pd.merge(left, right, on=["key1", "key2"], how="outer")

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

B.1.2 根据Df的索引列合成数据

某个数组待合并的键并不出现在列中,而是以索引的方式出现在数组中,也可以实现索引与列之间的连接。

  • right_index = True 使用右侧数组的索引为键值
  • left_index = True 使用左侧数组的索引为键值
  • 若一侧指定了多个列为键值,那么另一侧需要有对应的多层索引,也就是A.部分提到的知识。
#data
left1 = pd.DataFrame({"key": ["a", "b", "a", "a", "b", "c"],"value": pd.Series(range(6), dtype="Int64")})
right1 = pd.DataFrame({"group_val": [3.5, 7]}, index=["a", "b"])#这里左侧使用键,右侧使用索引
pd.merge(left1, right1, left_on="key", right_index=True)

在这里插入图片描述

在这里插入图片描述

B.1.3 合成的集合选择方式(how参数)

两个合并的数组,键值可能不完全相同,通过how参数可以指定结果使用哪种方式对键值进行选择

  • inner 使用两个数组共有的键值作为最终结果,即取交集(默认方式)
  • left 使用左侧数组的键值
  • right 使用右侧数组的键值
  • outer 使用二者相结合的键值,即取并集
    在这里插入图片描述
pd.merge(df1, df2,how='outer')
pd.merge(df1, df2,how='outer')
pd.merge(df1, df2,how='right')

在这里插入图片描述
在这里插入图片描述

B.1.4 合成时不作为键但列名相同的列(suffixes参数)

当不以重名的列作为键进行合并时,合并后为区分两个列会自动添加一个后缀
也可以使用suffixes参数手动指定添加的后缀 suffixes(‘_left’,‘_right’)

pd.merge(left, right, on="key1", suffixes=("_left", "_right"))

在这里插入图片描述

B.1.5 pd.merge参数总结(其他参数)

其他参数如下表,等待读者参考官方文档自行探索。
在这里插入图片描述

B.1.6 使用pd.join简化按索引列合并

上述pd.merge()方法在使用索引为键值的情况,参数略微有一些繁琐。而pd.join()方法 可以简化。

  • 当df1 和 df2 都以索引作为键进行合并时使用 df1.join(df2) 默认的连接方式为左连接(相当于how=left)
  • 当df1使用列 与df2的索引 作为键进行合并时,df1.join(df2,on=‘key’)
  • 可以使用join向df1插入多个数组 df1.join([df2,df3]) 默认的连接方式也是左连接
# data
left1 = pd.DataFrame({"key": ["a", "b", "a", "a", "b", "c"],"value": pd.Series(range(6), dtype="Int64")})
right1 = pd.DataFrame({"group_val": [3.5, 7]}, index=["a", "b"])
left2 = pd.DataFrame([[1., 2.], [3., 4.], [5., 6.]],index=["a", "c", "e"],columns=["Ohio", "Nevada"]).astype("Int64")
right2 = pd.DataFrame([[7., 8.], [9., 10.], [11., 12.], [13, 14]],index=["b", "c", "d", "e"],columns=["Missouri", "Alabama"]).astype("Int64")
another = pd.DataFrame([[7., 8.], [9., 10.], [11., 12.], [16., 17.]],index=["a", "c", "e", "f"],columns=["New York", "Oregon"])                      # df1.join(df2)
left2.join(right2)# df1.join(df2,how='outer')
left2.join(right2, how="outer")# df1.join(df,on='key') key是df1的键
left1.join(right1, on="key")# df1.join([df2,df3]) 
left2.join([right2, another])
left2.join([right2, another], how="outer")

在这里插入图片描述
在这里插入图片描述

2. pd.concat()按轴方向串联数据

  • pd.concat()会按照指定轴的方向,将数组以及索引都连接起来。
  • pd.concat()第一个参数制定待连接的对象,可以是列表的形式pd.concat([df1,df2’])
  • 默认连接方向是向下(沿行),如果需要向右拼接(沿列)需要指定参数 axis=‘columns’
  • 默认是取待串联的数组各个索引的并集。如需要取交集,需要指定参数join=‘inner’
  • 可以对被拼接的轴增加一层索引,通过keys参数指示来自哪个是数组pd.concat([df1,df2,df3],keys=[‘1’,‘2’,‘3’])
  • pd.concat()第一个参数制定待连接的对象,也可以是字典的形式pd.concat({‘l1’:df1,‘l2’:df2})这里l1 l2 也会给被拼接轴增加一层索引,指示数据来自哪个数组。
  • names参数可以对形成的多层索引命名。
  • 默认生成的新数组索引时原数组的拼接(沿轴串联保留索引),若想重新生成索引,使用ignore_index=True
# data 三个数组索引没有交集
s1 = pd.Series([0, 1], index=["a", "b"], dtype="Int64")
s2 = pd.Series([2, 3, 4], index=["c", "d", "e"], dtype="Int64")
s3 = pd.Series([5, 6], index=["f", "g"], dtype="Int64")# 默认横向拼接,默认取并集
pd.concat([s1, s2, s3])#纵向拼接
pd.concat([s1, s2, s3], axis="columns")#对于有重复的数据,取并集
s4 = pd.concat([s1, s3])
#取交集
pd.concat([s1, s4], axis="columns", join="inner")#依据数据来源设置分层索引
result = pd.concat([s1, s1, s3], keys=["one", "two", "three"])#data 两个Df
df1 = pd.DataFrame(np.arange(6).reshape(3, 2), index=["a", "b", "c"],columns=["one", "two"])
df2 = pd.DataFrame(5 + np.arange(4).reshape(2, 2), index=["a", "c"],columns=["three", "four"])#纵向拼接,按数据来源设置分层索引
pd.concat([df1, df2], axis="columns", keys=["level1", "level2"])
#也可以按字典方式设置分层索引并传入数据
pd.concat({"level1": df1, "level2": df2}, axis="columns")#默认索引是将原来的拼接在一起但是也可以指定重新排雷索引
df1 = pd.DataFrame(np.random.standard_normal((3, 4)),columns=["a", "b", "c", "d"])
df2 = pd.DataFrame(np.random.standard_normal((2, 3)),columns=["b", "d", "a"])
pd.concat([df1, df2], ignore_index=True)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3. df.combine_first()实现有重复索引的选择性拼接

pd.merge可以实现将重复索引作为键值,连接其他列
pd.concat 可以实现将重复索但值不同会合成不同的行
而df.combine_first()可以实现对于重复色索引,但是值不同,选择其中某个数组的值行层新的列。
a.combine_first(b)实现的功能类似于np.where(pd.sina(a),b,a) ,也就是说当a为空值时,选择b的值填入,当a为非空时选择a的值。
对于Df来说,就是对每一列进行上述操作。

# data
a = pd.Series([np.nan, 2.5, 0.0, 3.5, 4.5, np.nan],index=["f", "e", "d", "c", "b", "a"])
b = pd.Series([0., np.nan, 2., np.nan, np.nan, 5.],index=["a", "b", "c", "d", "e", "f"])#以下两个命令类似
np.where(pd.isna(a), b, a)
a.combine_first(b)#data
df1 = pd.DataFrame({"a": [1., np.nan, 5., np.nan],"b": [np.nan, 2., np.nan, 6.],"c": range(2, 18, 4)})
df2 = pd.DataFrame({"a": [5., 4., np.nan, 3., 7.],"b": [np.nan, 3., 4., 6., 8.]})
df1.combine_first(df2)                    

在这里插入图片描述

C. 数据透视表

C.1 df.pivot

假设现在数据的解构如下表,item列代表不同的键(可以转换成很多列),value代表不同的值
在这里插入图片描述
现要将其转换为常规Df的新式,即每一列都是一种数据使用Df.pivot(index= ,columns=‘item’,value=)
如下图:
在这里插入图片描述

  • 达到的效果和把item列移动到列索引类似。
    在这里插入图片描述

C.2 pd.melt

pd.melt 与df.pivot达到的效果相反。
pd.melt(df,id_vars=‘key’)会将Df的各列合并成一列,其中id_vars可以不指定
在这里插入图片描述
使用pivot复原
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/107256.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

chatGPT-对话柏拉图

引言: 古希腊哲学家柏拉图,在他的众多著作中,尤以《理想国》为人所熟知。在这部杰作中,他勾勒了一个理想的政治制度,提出了各种政体,并阐述了他对于公正、智慧以及政治稳定的哲学观点。然而,其…

C++ 网络编程项目fastDFS分布式文件系统(八)--

目录 1 程序中的相关协议 1 程序中的相关协议 1. 注册 客户端 // url http: //127.0.0.1:80/reg // post 数据格式 { userName:xxxx, nickName:xxx, firstPwd:xxx, phone:xxx, email:xxx } 服务器 成功 {"code":"002"} 该用户已存在 {&q…

solidity0.8.0的应用案例13:数字签名及应用:NFT白名单

以太坊中的数字签名ECDSA,以及如何利用它发放NFT白名单 代码中的ECDSA库由OpenZeppelin的同名库简化而成。 数字签名 如果你用过opensea交易NFT,对签名就不会陌生。下图是小狐狸(metamask)钱包进行签名时弹出的窗口,它可以证明你拥有私钥的同时不需要对外公布私钥。 …

Shell基础_Shell概述及脚本执行方式

文章目录 1. Shell概述1.1 Shell是什么1.2 Shell的分类1.3 Linux支持的Shell1.4 总结 2. Shell脚本的执行方式2.1 echo输出命令2.2 第一个脚本2.3 脚本执行 1. Shell概述 1.1 Shell是什么 Shell是一个命令行解释器,它为用户提供了一个向Linux内核发送请求以便运行…

【Java 动态数据统计图】前后端对接数据格式(Map返回数组格式数据)六(120)

说明: 前端使用:vue3.0 前后端对接数据格式:无非就是前端把后端返回的数据处理为自己想要的格式,或者,后端给前端处理好想要的格式; 针对前后端的柱状图,趋势图等数据对接,前端一般需…

ModaHub魔搭社区:WinPin经营大脑助手

产品介绍 智慧经营助手:企业专属的“数据工程师”“BI分析师” WinPlan决策系统 算力 阿里云 腾讯云 AWS亚马逊 框架 业务数据基座 WinPlan垂直大模型 模型 分析模型 预测模型 决策模型 应用 精准预测

springboot整合第三方技术邮件系统

springboot整合第三方技术邮件系统,发邮件是java程序的基本操作,springboot整合javamail其实就是简化开发。不熟悉邮件的小伙伴可以先学习完javamail的基础操作,再来看这一部分内容才能感触到springboot整合javamail究竟简化了哪些操作。简化…

“R语言+遥感“水环境综合评价方法

详情点击链接:"R语言遥感"水环境综合评价方法 一:R语言 1.1 R语言特点(R语言) 1.2 安装R(R语言) 1.3 安装RStudio(R语言) (1)下载地址 &…

研磨设计模式day11代理模式

目录 场景 代码实现 ​编辑 解析 定义 代理模式调用示意图 代理模式的特点 本质 ​编辑何时选用 场景 我有一个订单类,包含订单数、用户名和商品名,有一个订单接口包含了对订单类的getter和setter 现在有一个需求,a创建的订单只…

Leetcode每日一题:1448. 统计二叉树中好节点的数目(2023.8.25 C++)

目录 1448. 统计二叉树中好节点的数目 题目描述: 实现代码与解析: dfs 原理思路: 1448. 统计二叉树中好节点的数目 题目描述: 给你一棵根为 root 的二叉树,请你返回二叉树中好节点的数目。 「好节点」X 定义为&…

机器学习实战之用 Scikit-Learn 正则化方法解决过拟合详解

你是不是在模型训练中遇到过这样的问题:在训练集上表现得极好,但在测试集上效果不佳?这就是过拟合的问题。 过拟合是模型在训练过程中学到了数据的“噪声”而非规律,导致在未知数据上表现不佳。那么怎么解决这个问题呢&#xff1…

计算机丢失msvcp110.dll是什么意思?有哪些方法可以修复

今天,我将和大家一起探讨一个关于计算机的问题——“计算机丢失msvcp110.dll是什么意思?有哪些方法可以修复?”这个问题在我们的日常生活中非常常见,尤其是在使用Windows系统的过程中,可能会遇到这样的问题。那么&…

ctfshow web入门 php特性 web108-web112

1.web108 strrev() 反转字符串 <?php echo strrev("Hello world!"); // 输出 "!dlrow olleH" ?> ereg 存在空字符截断(只会匹配%00前面的字符)&#xff0c;这个函数匹配到为true&#xff0c;没有匹配到为false,877为0x36d的十进制数值 payload: …

后端开发有哪几种语言? - 易智编译EaseEditing

后端开发是构建应用程序的一部分&#xff0c;负责处理服务器端的逻辑、数据库交互和数据处理。有许多编程语言可用于后端开发&#xff0c;以下是一些常见的后端开发语言&#xff1a; Java&#xff1a; Java是一种广泛使用的面向对象编程语言&#xff0c;具有强大的跨平台能力。…

哪款运动耳机好用、舒服的运动耳机推荐

如今&#xff0c;运动耳机已成为备受热捧的运动潮流单品&#xff0c;消费者对耳机的需求非常多元化。一款出色的运动耳机不仅要满足基本的运动需求&#xff0c;还需要具备丰富的功能&#xff0c;这直接决定了耳机的附加价值。接下来&#xff0c;我将向大家推荐5款佩戴舒适、牢固…

【C++】map的奇葩用法:和函数结合

2023年8月26日&#xff0c;周六下午 今天才发现map居然还能这样用... #include <iostream> #include <map> #include <functional>void printOne() {std::cout << "已经打印出1" << std::endl; }void printTwo() {std::cout <<…

nrm管理源仓库及发布私人npm包

使用nrm管理源及切换源仓库 1.安装nrm源管理器 npm install nrm -g2.查看目前现有的源仓库 通过 nrm ls 查看现有的源 nrm ls 输出&#xff1a;这是目前现有的源 3.切换不同的源 可以通过 nrm use xxx&#xff08;源仓库名&#xff09;来切换不同的源地址 nrm use taobao…

Spark 7:Spark SQL 函数定义

SparkSQL 定义UDF函数 方式1语法&#xff1a; udf对象 sparksession.udf.register(参数1&#xff0c;参数2&#xff0c;参数3&#xff09; 参数1&#xff1a;UDF名称&#xff0c;可用于SQL风格 参数2&#xff1a;被注册成UDF的方法名 参数3&#xff1a;声明UDF的返回值类型 ud…

SpringBoot+WebSocket搭建多人在线聊天环境

一、WebSocket是什么&#xff1f; WebSocket是在单个TCP连接上进行全双工通信的协议&#xff0c;可以在服务器和客户端之间建立双向通信通道。 WebSocket 首先与服务器建立常规 HTTP 连接&#xff0c;然后通过发送Upgrade标头将其升级为双向 WebSocket 连接。 WebSocket使得…

一个简单的web应用程序的创建

一个简单的web应用程序的创建 1、数据库设计与创建1.1、数据库系统1.2、Navicat Premium1.3、Power Designer2、使用maven创建SpringBoot项目2.1、配置maven2.2、安装idea2.3、使用idea创建maven项目2.4、根据需要配置pom.xml文件、配置项目启动相关的文件2.5、写SpringBoot项目…