数据处理与统计分析——07-Pandas的concat连接、merge()合并、多表查询、内/外/自连接查询操作

pandas数据拼接

(1) DataFrame数据组合-concat连接

  • 概述

    • 连接是指把某行或某列追加到数据中, 数据被分成了多份可以使用连接把数据拼接起来
    • 把计算的结果追加到现有数据集,也可以使用连接
  • df对象与df对象拼接

    行拼接参考: 列名, 列拼接参考: 行号

    # todo 记忆: concat()函数既能实现行拼接(默认), 也能实现列拼接.   行拼接参考: 列名,   列拼接参考: 索引列(行索引)
    # 1. 演示行拼接
    pd.concat([df1, df2, df3])                  # 默认是: 行拼接.
    pd.concat([df1, df2, df3], axis='rows')     # 效果同上
    pd.concat([df1, df2, df3], axis=0)          # 效果同上, 0 => rows, 行,   1 => columns, 列# 2. 演示列拼接
    pd.concat([df1, df2, df3], axis='columns')  # 列拼接
    pd.concat([df1, df2, df3], axis=1)          # 效果同上# 3. 演示 行, 列拼接时, 重置: 索引 和 列名
    # todo 细节: 无论是行, 列拼接时, 只要忽略索引了, 都会默认用 0 ~ n来填充.
    pd.concat([df1, df2, df3], axis='rows', ignore_index=True)     # 行拼接
    pd.concat([df1, df2, df3], axis='columns', ignore_index=True)     # 列拼接# 4. 验证 行拼接时, 参考: 列名
    df4 = pd.DataFrame(['n1', 'n2', 'n3'], columns=['B'], index=['a', 1, 'c'])
    df4# 5. 拼接 df1 和 df4
    # 行拼接, 参考: 列名
    pd.concat([df1, df4], axis='rows')      # 未匹配, 用NAN填充.# 列拼接, 参考: 索引列
    pd.concat([df1, df4], axis='columns')   # 未匹配, 用NAN填充.
    
  • df对象 和 Series对象拼接

    # 1. 创建Series对象.
    s1 = pd.Series(['n1', 'n2', 'n3'])      
    s1  # todo Series对象代表一列数据, 他没有类似于df的列名, 所以 行拼接时, 类似于: 新增了1列 
    #%%
    # 2. 使用concat拼接df和series对象.
    pd.concat([df1, s1], axis='rows')        # 默认是: 行拼接.
    pd.concat([df1, s1], axis='columns')     # 默认是: 列拼接.
    #%%
    # 3. 细节, 关于append()函数, 旧版本的Anaconda(例如: Anaconda2020)支持, 新版本中已经被移除掉了, 它能实现的事儿, 用concat()都能做. 
    # df1.append(df2)     # 报错
    pd.concat([df1, df2]) # 可以平替上述的功能
    
  • df对象新增列

    # 方式1: df对象[列名] = 列表, 要求: 列表的长度 要和 df的行数一致.
    # df1['new_col1'] = [10, 20, 30]        # 报错, 值的个数 和 行数(4行)不匹配
    df1['new_col1'] = [10, 20, 30, 40]      # 正确
    df1# 上述的代码, 加入 concat()
    df5 = pd.concat([df1, df2], axis=1)       # 列拼接
    df5['new_col1'] = [10, 20, 30, 40]
    df5# 方式2: df对象[列名] = Series对象, Series对象值的个数无要求.
    df1['new_col2'] = pd.Series([1, 2, 3])
    df1['new_col3'] = pd.Series([1, 2, 3, 4])
    df1['new_col4'] = pd.Series([1, 2, 3, 4, 5])
    df1
    
  • append函数演示

    append()函数已过时, 它作用和concat()类似, 在新版的pandas中这个方法已经被删除了.

    # concat可以连接多个对象, 例如: df1, df2, df3...
    # 但如果只需要像现有的df对象, 添加1个对象, 可以使用 append()函数实现.# 演示 append函数, 实现: 追加1个df对象 到 另1个df对象中.
    df1.append(df2)  # 只能行拼接, 且没有axis参数# ignore_index: 忽略索引, 即: 索引会重置. 
    df1.append(df2, ignore_index=True)# df对象 使用append追加一个字典时, 必须传入 ignore_index=True 参数
    data_dict = {'A': 'n1', 'B': 'n2', 'C': 'n3'}
    df1.append(data_dict, ignore_index=True)
    

(2) merge()函数

  • 概述

    • 在使用concat连接数据时,涉及到了参数join(join = ‘inner’,join = ‘outer’)

    • 数据库中可以依据共有数据把两个或者多个数据表组合起来,即join操作

    • DataFrame 也可以实现类似数据库的join操作

      • Pandas可以通过pd.join命令组合数据,

      • 也可以通过pd.merge命令组合数据

        merge更灵活,如果想依据行索引来合并DataFrame可以考虑使用join函数

    • 多表查询分类
      >连接查询
      内连接相当于A、B交集部分数据(无null值)
      外链接:有(null)值
      左外连接:查询左表所有数据,
      以及两张表交集部分数据
      右外连接:查询右表所有数据,
      以及两张表交集部分数据
      自连接当前表与自身的连接查询,自连接必须使用表别名

  • 准备数据

    # 1. 创建链接对象 关联 db文件
    import sqlite3
    conn = sqlite3.connect('data/chinook.db')# 2. 从上述的文件中, 读取 歌曲表的信息
    # 参1: 要执行的 sql语句    # 参2: 连接对象
    tracks_df = pd.read_sql_query('select * from tracks', conn)
    tracks_df.head()# 3. 从上述文件中, 读取 歌曲分类表的信息
    genres_df = pd.read_sql_query('select * from genres', conn)
    genres_df.head()
    
  • merge()合并数据, 一对一

    # 1. 查看 歌曲风格表的信息
    genres_df# 2. 查看 歌曲表的信息, 并从中找到 不同的音乐风格的数据.
    tracks_subset_df = tracks_df.loc[[0, 62, 76, 98, 110, 193, 204, 281]]
    tracks_subset_dftracks_subset_df[['TrackId', 'GenreId', 'Milliseconds']]        # 歌曲id, 风格id, 歌曲时长(毫秒)# 3. 合并上述两个表, 以 风格 为标准, 合并.
    """
    # 场景1: 内连接
    # 参1: 要被合并的df对象. 
    # 参2: on表示两个df合并的 关联字段, 如果一样可以直接写 on, 如果不一样, 则要写 left_on='左表字段名', right_on='右表字段名'
    # 参3: how表示合并方式, 内连接: inner, 左连接: left, 右连接: right, 全(满)连接: outer
    """
    genres_df.merge(tracks_subset_df[['TrackId', 'GenreId', 'Milliseconds']], on='GenreId', how='inner')# 场景2: 左外连接
    genres_df.merge(tracks_subset_df[['TrackId', 'GenreId', 'Milliseconds']], on='GenreId', how='left')# 场景3: 右外连接
    genres_df.merge(tracks_subset_df[['TrackId', 'GenreId', 'Milliseconds']], on='GenreId', how='right')# 场景4: 满外连接, 也叫: 全连接, 即: 它的查询结果 = 左连接 + 右连接,   即: 左表全集 + 右表全集 + 交集.
    genres_df.merge(tracks_subset_df[['TrackId', 'GenreId', 'Milliseconds']], on='GenreId', how='outer')# 场景5: 查看默认是哪种连接. 
    genres_df.merge(tracks_subset_df[['TrackId', 'GenreId', 'Milliseconds']], on='GenreId')     # 默认是: 内连接 => inner# 场景6: 如果关联的多个df有重名的列, 则默认会加上 _x, _y这样的后缀, 来源于: suffixes字段.
    genres_df.merge(tracks_subset_df[['TrackId', 'Name', 'GenreId', 'Milliseconds']], on='GenreId')     # 默认后缀: _x, _y
    genres_df.merge(tracks_subset_df[['TrackId', 'Name', 'GenreId', 'Milliseconds']], on='GenreId', suffixes=('_left', '_right'))     # 默认后缀: _x, _y
    

    细节:

    1. on 连接的字段, 如果左右两张表 连接的字段名字相同直接使用 on=‘关联字段名’

    2. 如果名字不同, left_on 写左表字段, right_on 写右表字段.

    3. 连接之后, 两张表中如果有相同名字的字段, 默认会加上后缀 默认值 _x, y

      suffixes:(" x", “_ y”)

  • merge()合并数据, 一对多

    # todo merge()格式: df1.merge(df2, on='关联字段', how='连接方式')
    # todo 参数: 1. how默认是 inner      2. 关联字段不一致时, 用 left_on 和 right_on     3. 两个df的字段有重名, 可以通过 suffixes 指定后缀# 需求2: 计算每种类型音乐的 平均时长
    # todo 1. 合并 genres(风格表) 和 tracks(歌曲表). 交集
    # genres_tracks = genres_df.merge(tracks_df[['TrackId', 'GenreId', 'Milliseconds']], on='GenreId', how='inner')# 左外连接
    # 风格表.merge(歌曲表[['歌曲id', '风格id', '歌曲时长毫秒']])
    genres_tracks = genres_df.merge(tracks_df[['TrackId', 'GenreId', 'Milliseconds']], on='GenreId', how='left')
    genres_tracks# todo 2. 根据 风格id分组, 计算 歌曲时长的平均值 (分组聚合)
    genre_time = genres_tracks.groupby(['GenreId', 'Name']).Milliseconds.mean()
    genre_time# 3. 扩展: 把上述的 genre_time(毫秒) -> 秒
    pd.to_timedelta(genre_time, unit='ms').dt.floor('s')
    pd.to_timedelta(genre_time, unit='ms').dt.floor('s').sort_values()
    # pd.to_timedelta(genre_time, unit='ms') 把genre_time的毫秒数, 转换成 pandas.Timedelta 类型
    # dt.floor('s') : 取整, 取秒
    

(3) DataFrame数据组合-join()

概述

  • 使用join合并,可以是依据两个DataFrame的行索引,
  • 或者一个DataFrame的行索引另一个DataFrame的列索引进行数据合并
# 1. 加载数据, 获取df对象.
stock_2016 = pd.read_csv('data/stocks_2016.csv')
stock_2017 = pd.read_csv('data/stocks_2017.csv')
stock_2018 = pd.read_csv('data/stocks_2018.csv')
stock_2016
stock_2017
stock_2018# 2. 默认情况下, join会参考 两个df的 索引列 进行合并连接.
stock_2016.join(stock_2017, lsuffix='_2016', rsuffix='_2017')               # 默认: 左外连接
stock_2016.join(stock_2017, lsuffix='_2016', rsuffix='_2017', how='left')   # 效果同上# 3. 设置两个df对象的 Symbol列为索引列, 再次关联.
stock_2016.set_index('Symbol')
stock_2017.set_index('Symbol')# 设置索引列, 并关联. 
stock_2016.set_index('Symbol').join(stock_2017.set_index('Symbol'), lsuffix='_2016', rsuffix='_2017', how='left')   # 左外连接
stock_2016.set_index('Symbol').join(stock_2017.set_index('Symbol'), lsuffix='_2016', rsuffix='_2017', how='right')  # 右外连接
stock_2016.set_index('Symbol').join(stock_2017.set_index('Symbol'), lsuffix='_2016', rsuffix='_2017', how='outer')  # 满外连接
stock_2016.set_index('Symbol').join(stock_2017.set_index('Symbol'), lsuffix='_2016', rsuffix='_2017', how='inner')  # 内连接# 4. 设置stock_2016的索引为: Symbol 和 stock_2018做关联.
stock_2016
stock_2018.set_index('Symbol')# 拿着 stock_2016的 指定列(普通列) 和 stock_2018的 索引列 进行关联.
# 细节: on参数设定的是 函数外 df对象的 普通列
stock_2016.join(stock_2018.set_index('Symbol'), lsuffix='_left', rsuffix='_right', on='Symbol', how='outer')# 总结: join() => 1. 默认是 左外连接.      2.如果两个df有重名字段, 需要手动设置后缀名.    3.默认是根据两个df的 索引列来合并的, 如果想要关联普通列, 需要通过 on 参数实现.

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

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

相关文章

EwoMail邮箱服务器软件安装教程

EwoMail是基于Linux的开源邮件服务器软件,集成了众多优秀稳定的组件,是一个快速部署、简单高效、多语言、安全稳定的邮件解决方案,帮助你提升运维效率,降低 IT 成本,兼容主流的邮件客户端,同时支持电脑和手机邮件客户端。 一、系统版本 二、关闭selinux vi /etc/sysconf…

【机器学习】机器学习的基本分类-监督学习-支持向量机(Support Vector Machine, SVM)

支持向量机是一种强大的监督学习算法,主要用于分类问题,但也可以用于回归和异常检测。SVM 的核心思想是通过最大化分类边界的方式找到数据的最佳分离超平面。 1. 核心思想 目标 给定训练数据 ,其中 是特征向量, 是标签&#xf…

Linux命令进阶·如何切换root以及回退、sudo命令、用户/用户组管理,以及解决创建用户不显示问题和Ubuntu不显示用户名只显示“$“符号问题

目录 1. root用户(超级管理员) 1.1 用于账户切换的系统命令——su 1.2 退回上一个用户命令——exit 1.3 普通命令临时授权root身份执行——sudo 1.3.1 为普通用户配置sudo认证 2. 用户/用户组管理 2.1 用户组管理 2.2 用户管理 2.2.1 …

Zero to JupyterHub with Kubernetes中篇 - Kubernetes 常规使用记录

前言:纯个人记录使用。 搭建 Zero to JupyterHub with Kubernetes 上篇 - Kubernetes 离线二进制部署。搭建 Zero to JupyterHub with Kubernetes 中篇 - Kubernetes 常规使用记录。搭建 Zero to JupyterHub with Kubernetes 下篇 - Jupyterhub on k8s。 参考&…

《Python基础》之Python中可以转换成json数据类型的数据

目录 一、JSON简介 JSON有两种基本结构 1、对象(Object) 2、数组(Array) 二、将数据装换成json数据类型方法 三、在Python中,以下数据类型可以直接转换为JSON数据类型 1、字典(Dictionary&#xff09…

若依项目源码阅读

源码阅读 前端代码分析 代码生成器生成的前端代码有两个,分别是course.js用于向后端发送ajax请求的接口代码,另一个是index.vue,用于在浏览器展示课程管理的视图组件。前端的代码是基于vue3elementplus。 template用于展示前端组件别的标签…

C#tabcontrol如何指定某个tabItem为默认页

// Selects tabPage2 using SelectedTab.this.tabControl1.SelectedTab tabPage2; 参考链接 TabControl.SelectedTab 属性 (System.Windows.Forms) | Microsoft Learnhttps://learn.microsoft.com/zh-cn/dotnet/api/system.windows.forms.tabcontrol.selectedtab?viewnetfr…

速盾:高防 CDN 可以配置客户端请求超时配置?

在高防 CDN(Content Delivery Network,内容分发网络)的运行管理中,客户端请求超时配置是一项重要的功能设定,它对于优化网络资源分配、保障服务质量以及维护系统稳定性有着关键意义。 一、客户端请求超时配置的概念 …

文件比较和文件流

文件比较和文件流 一、文本比较工具 diff1.基本用法1.1输出格式 2.常用选项 二、文件流1.文件的打开模式2.文件流的分类ifstreamofstreamfstrem区别 3.文件流的函数1. 构造函数2. is_open 用于判断文件是否打开3. open4. getline5. close6. get()7. read8. write9. put10. gcou…

【网络篇】HTTP知识

键入网址到网页显示,期间发生了什么? 浏览器第一步是解析URL,这样就得到了服务器名称和文件的路径名,然后根据这些信息生成http请求,通过DNS查询得到我们要请求的服务器地址,然后添加TCP头、IP头以及MAC头&…

【解决安全扫描漏洞】---- 检测到目标站点存在 JavaScript 框架库漏洞

1. 漏洞结果 JavaScript 框架或库是一组能轻松生成跨浏览器兼容的 JavaScript 代码的工具和函数。如果网站使用了存在漏洞的 JavaScript 框架或库,攻击者就可以利用此漏洞来劫持用户浏览器,进行挂马、XSS、Cookie劫持等攻击。 1.1 漏洞扫描截图 1.2 具体…

互联网基础

TCP/IP协议(协议组) 分层名称TCP/IP协议应用层HTTP,FTP,mDNS,WebSocket,OSC...传输层TCP,UDP网络层IP链路层(网络接口层)Ethernet,Wi-Fi... 链路层(网络接口层) 链路层的主要作用…

【分组去重】.NET开源 ORM 框架 SqlSugar 系列

💥 .NET开源 ORM 框架 SqlSugar 系列 🎉🎉🎉 【开篇】.NET开源 ORM 框架 SqlSugar 系列【入门必看】.NET开源 ORM 框架 SqlSugar 系列【实体配置】.NET开源 ORM 框架 SqlSugar 系列【Db First】.NET开源 ORM 框架 SqlSugar 系列…

hdlbits系列verilog解答(Exams/m2014 q4d)-89

文章目录 一、问题描述二、verilog源码三、仿真结果一、问题描述 本节实现以下电路。 模块声明 module top_module ( input clk, input in, output out); 思路: 它的输入是一个组合逻辑异或门,将输入和输出异或后输入D触发器,这意味着输出与历史输出及当前输入都有关系,…

Cesium K-means自动聚合点的原理

Cesium K-means自动聚合点的原理 Cesium 是一个开源的 JavaScript 库,用于在 Web 环境中创建 3D 地球和地图应用。它能够处理地理空间数据,并允许开发者对大规模的地理数据进行可视化展示。在一些应用中,尤其是当处理大量地理坐标点时&#…

计算机网络课程设计:理论与实践全解析

标题:计算机网络课程设计:理论与实践全解析 计算机网络课程设计是计算机专业培养学生动手能力和理论联系实际的重要环节。通过设计并实现实际项目,学生能够更深刻地理解网络协议、网络通信及应用开发的核心技术。本文将从课程设计的选题、实施…

【代码随想录|贪心算法02】

122.买股票的最佳时机 题目链接https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-ii 好巧妙的一道题啊,做之前完全不会想到这种解法。 局部最优:收集每天正利润 全局最优:求得最大利润 这道题只让你返回最大的利润和&…

网络安全开源组件

本文只是针对开源项目进行收集,如果后期在工作中碰到其他开源项目将进行更新。欢迎大家在评论区留言,您在工作碰到的开源项目。 祝您工作顺利,鹏程万里! 一、FW(防火墙) 1.1 pfSense pfSense项目是一个免费…

将面具贴到人脸上的过程

使用OpenCV进行人脸面具贴合和变形以适应人脸的3D透视角度,通常需要以下步骤: 人脸检测:首先需要检测图像中的人脸位置。特征点检测:在检测到的人脸区域中,找到关键特征点,如眼睛、鼻子、嘴巴等。透视变换…

Kafka如何保证消息可靠?

大家好,我是锋哥。今天分享关于【Kafka如何保证消息可靠?】面试题。希望对大家有帮助; Kafka如何保证消息可靠? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Kafka通过多种机制来确保消息的可靠性,主要包…