范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

错得离谱!竟然说pandas中的join比merge快5倍?我带你看源码吧

  前言
  最近有两位小伙伴跟我说,网上看到一篇文章说,在 python 中使用 pandas 连接两个表,别用 merge ,要使用 join,因为在大量数据的情况下 join 比 merge 要快4到5倍。
  其实这说法我一听就知道是错误的。不过当时没有具体证据支持,所以我也没有下具体结论。
  今天,我就从源码的角度,给大家一个参考依据。
  当然,本文你还会学到一些代码调试技巧,还会看到一些 pandas 的优化手段。
  join 比 merge 快很多?
  那篇文章中的测试大概如下: import pandas as pd import numpy as np from time import time  high = 1000 rows_list = [(i + 1) * 1_000_000 for i in range(10)] n_columns = 4 repeat = 5  def create_df(n_rows, n_columns, col_names):     data = np.random.randint(low=-high, high=high, size=(n_rows, n_columns))     index_col = np.arange(0, n_rows)     np.random.shuffle(index_col)     data = pd.DataFrame(data, columns=col_names, dtype=np.int16)     data["idx"] = index_col     return data for n_rows in [10_000_000]:     sum_time_merge1 = 0     sum_time_merge2 = 0      for _ in range(repeat):         df1 = create_df(n_rows, n_columns, [f"col_{i}" for i in range(n_columns)])         df2 = create_df(n_rows, n_columns, [f"Col_{i}" for i in range(n_columns)])          # merge         start = time()         df = pd.merge(df1, df2, how="left",left_on = "col_0",right_on="Col_0")         sum_time_merge1 += time() - start          ## join         start = time()         df1.set_index("idx", inplace=True)         df2.set_index("idx", inplace=True)         df = df1.join(df2)         sum_time_merge2 += time() - start      result.append([df1.shape[0], sum_time_merge1 / repeat, sum_time_merge2 / repeat])  print(pd.DataFrame(result, columns=["行数", "merge耗时(秒)", "join耗时(秒)"])) 跑一千万数据,5次,取个平均 使用 df.join 有个前提,把2个表的关联key的列设置为行索引 merge 则使用普通的列作为关联key 我这里生成的key 是唯一的。足以复现原文的效果
  看看结果:
  嗯?还真快了这么多!
  但是为什么我一开始听到这说法,不用做任何的实验,就觉得这观点有问题?
  其实道理很简单。
  假如今天你实现了一个功能函数:
  功能很简单,把一个列表中的数值,先转成正数,然后求和
  明天,你需要实现另一个功能很接近的函数,只不过输入的不是列表,而是2个具体的数值。显然你会想着调用之前的函数:
  同样道理,join 函数明显是 merge 函数的一个特例。pandas 的设计者不会傻到用两套不一样的方式实现它们。
  但是,别人给出来的实验结果确确实实反应了它们的差异。
  接下来,我们就看看它们实现的源码。 源码找答案
  首先,新建一个 python 文件,把代码设置得简单一些。
  打开调试窗口,点击创建 python 的调试配置。
  这里最重要的是设置  justMyCode   为 false 。这样子我们才能进入 pandas 源码里面
  接着,在 merge 函数那一行打开一个断点
  执行调试
  代码会停在断点的行,接着我们要点击控制菜单中的下一步(也可以用快捷键)。
  可以看到,merge 函数实际调用的是  pandas.core.reshape.merge.merge   ,暂时不深入
  如果你看过我之前关于类定义的文章,那么不用看里面的实现也知道,这里只不过实例化了一个对象,记录了一些相关数据而已,重要的是下方的 get result 函数
  同样道理,调试 join 函数
  咦?它的实现与 merge 不一样?别急,继续执行,直到
  进入一看,又跳回到之前 merge 函数的实现
  从左侧的调用堆栈中可以看到调用顺序:
  1 是join调用 2 是  join  compat 3 就是上图右边的代码
  你可以点击调用堆栈中的一行,代码会跳回去,就连当时执行中的所有变量的值都可以查看
  简单列一下大概的调用图:
  join 函数绕了一圈才到真正执行的地方
  所以现在我们知道,join 函数其实比 merge 函数执行更多的代码。
  但是,之前的实验数据很好地说明了 join 比 merge 快呀,为什么? 不公平的对比
  按调试流程,我们进入之前看到的 op.get result 函数里面:
  进入这个  self._get_join_info()   里面:
  可以看到许多关于 left index 和 right index 参数的判断。但是  我们使用 merge 的时候根本没有设置这两个参数,它们都是 False。
  结果就会进入这段代码:
  这是一个 python 的遍历代码,一个个去匹配 key 值
  而 join 函数执行的却是:
  直接调用行索引对象的函数
  了解这些要点,相信聪明的你也知道要这样子修改实验代码:
  把设置行索引的代码移除两个函数执行的范围外 merge 设置参数 left  index 与 right  index
  但是,结果却出乎意料!!
  对比一下之前的时间:
  解释一下差异: join 的耗时短了很多,因为现在它没有设置行索引的操作 merge 耗时也短了很多,因为现在它内部用了行索引
  但是,为什么 merge 耗时仍然比 join 要慢很多? pandas 的优化
  此时,我们把实验代码中执行 merge 和 join 的先后顺序调换一下:
  注意,记录时间的变量的对应关系没有变,所以这不会影响结果表格的左右顺序
  看看结果:
  现在,结论截然相反!
  为什么?显然,有什么东西在第二次运行的时候,得到了优化。
  在之前的源码调试中,我们得知,其实两个表按行索引关联,最核心的计算就是行索引对象的 join 函数。
  按这个原理以及之前的调试方式,可以找到一个属性。具体过程我就不再啰嗦了,直接给出验证结果:
  在 join 的过程中,有一个判断逻辑,如果行索引的值都是唯一的,那么会进行一些操作。
  直接看看它的源码
  缓存了结果。
  道理很简单,  pandas 怎么可以知道一个行索引的值是否唯一?显然要遍历一次数据。这个过程在大量数据的时候成本很高。由于索引对象是不可变的,所以可以缓存结果。
  那么,现在我们修正一下测试实验的代码,让它公平对待:
  现在的结果是:
  很多小伙伴问我怎么学习 pandas 。正如我专栏里面的思路,集中学习少数核心常用的函数和原理,你的学习之路才能事半功倍。
  不要忘记一键三连。你的点赞、收藏、关注,是我创作的动力。
  推荐文章: python为什么需要函数、类这些概念懂Excel轻松入门Python数据分析pandas(18):pandas 中的vlookuppandas每天一题-题目19:"炸列"操作的多种方式pandas新版本增强功能,数据表多列频率统计

买便宜机票却没捞到便宜?记者替读者算了一笔账一名乘客购买廉价航空的机票,却因为行李超重被交了1807元的托运费。不含免费的托运行李额度餐食等附加服务,是廉价航空公司的惯例。可是,搭乘廉价航空并不意味着经常被算计。为此,记者替30多家旅行社负责人到周口野生动物园踩线驻马店广电融媒体记者胡海洋庄皓4月12日,驻马店市旅行社组织市县区30多家旅行社负责人到周口市野生动物园进行踩线体验。活动中,景区工作人员详细介绍了园区便捷的交通优势和地理位置等。有趣的化学反应,三原子反应的立体动力学文采风百晓生编辑采风百晓生在阅读此文之前,麻烦您点击一下关注,既方便您进行讨论和分享,又能给您带来不一样的参与感,感谢您的支持。介绍三原子反应是自然界中发生的最重要最有趣的化学反应甘肃兰州四月春光好两山造林忙甘肃省兰州市是黄河唯一穿城而过的省会城市,也是黄河上游生态修复的重要地区。眼下,随着气温回暖,兰州市城关区干部群众持续在主城区的南北两山植树播绿,筑牢黄河生态安全屏障,营造良好生态研学美丽宜居乡村,感受家乡发展快看,水底下有小鱼这花开的好美啊近日,在位于青岛市即墨区蓝村街道王演庄新村的三泉水韵景点区,迎来了一批参与研学活动的学生,他们三五成群,沿着蜿蜒的三泉河或看或思,或写或画,认真探索钟哥谈养生第四集茶叶不要乱喝哦,也要看体质!朋友们今天给大家聊一下喝茶。喝茶与养生有直接的关系。有些人喝茶不明白,茶分寒性中性和热性。寒性的茶,凉性的茶都有什么呢?清茶就是有些人叫绿茶,还有白茶。那么这些茶不适合生人去喝呢?市值暴跌4000亿,卖不动的长城汽车,是怎么走到如今这个地步的?俗话说,创业容易,守业难。短短一年时间过去,长城汽车已经跌得惨不忍睹,从峰值的6059亿到现如今的1876亿,长城算是亏了个大的。而且按目前的情况下,长城还完全没有想出止损的办法真樊振东差点被打懵!17岁神童爆冷崛起,排名飚升,王皓挖到宝最近国乒正在国内参加新乡冠军赛,对于我们来说,这一次还是希望能够拿到两个项目的冠军。尤其比赛又在家门口进行,没有理由输掉比赛。当然从最近的表现来看,中国队的主力没有辜负教练组的期待跳水皇后高敏拿过70枚金牌落一身伤病,如今53岁活成体育界李子柒阅读此文前,诚邀您点击一下关注,方便您随时查阅一系列优质文章,同时便于进行讨论与分享,感谢您的支持1992年12月27日,天津市人民体育馆里,一场由大型体坛大型电视文艺晚会正在进行21世纪的日不落帝国低调的法国依然遍布全世界现在这个世界上依然存在着日不落帝国,它就是法国。我们都知道法国在这里,但是这其实只是法国的一个版本,而另一个版本就是法国众多的海外领土。海外领土占法国国土面积的近20,海域面积更是比起皇帝的新衣,红毯更辣眼的玩法,出现了大概是生活太过乏味,大家的审美需求与日俱增。就连一向星光熠熠的红毯活动,也内卷起来。各个红毯都在忙着推陈出新,不再止步于定点拍照。自从前两年格莱美弄了一个高速慢镜头,运镜丝滑,群星
荣耀平板V7Pro一款学习办公趁手的工具精致外观下的轻巧便利荣耀平板V7Pro共有三个颜色晨晖金曙光蓝钛空银,每个颜色都各有特点也相当经典。我手里是曙光蓝配色,小牛皮质感的背壳,板正的直边设计,边框极窄,机身轻薄,满满的国乒解说到底谁最棒?蔡猛很菜,杨影又太主观,高菡目前呼声最高最近球迷们一定都在关注国乒的赛事进展选手成绩!比如王曼昱啊,许昕啊,劲爆消息频出!但是今天小编想跟大家聊聊乒乓球赛事解说!咱们国乒的御用解说到底谁合适?给小编点关注,乒乓球不迷路!CBA热身赛6大看点!2大超巨复出,2大超新星迎首秀,2队最受关注CBA新赛季将于10月16日开赛,目前各支球队整装待发,将于诸暨赛区集合,在10月11日14日,将进行一系列热身赛,倍受关注的辽宁广东浙江上海等球队都将一一亮相,具体有哪些看点,我太空的真面目究竟是什么样的?星河璀璨?还是一片漆黑最近我国的航天员在核心舱组合体上进行了第二次太空行走,当然在太空行走的时候,还是需要完成任务。在进行直播的时候,很多人都说这次真的是赚足了目光,很多人也想要知道在拍摄的时候,为什么神舟十三发射在即,有女宇航员加入,我国为何耗巨资发展航天事业神舟十二号载人飞船才返回不久,我国又准备向太空发射神舟十三号,并且此次可能还有女性宇航员的加入,女性宇航员的加入究竟有什么好处?我国现在耗巨资发展航天事业,真的只是为了满足人类的好神舟飞船系列之神舟一号踩点完成世纪任务神舟一号1992年9月21日,我国载人航天工程获得中央批复立项,中国航天开启了一个全新的时代载人航天时代。中国载人航天工程由七大系统组成,即航天员系统飞船应用系统载人飞船系统运载火女神刘诗诗的好命人生,和她生命中最爱的一个男人提到气质型的美女,就不得不提刘诗诗。而且人淡如菊的她,出道以来一直非常低调,最主要的是没有传出过任何绯闻。嫁给了吴奇隆后,更是成为了贤妻良母,堪称人生赢家。所以,在众多女演员中,刘宋庆龄病危,邀宋美龄回国见最后一面,宋美龄拒绝回国令人寒心1980年,宋庆龄心脏病愈加严重,身边却没有一个亲人陪伴。在病情危急的时候,她最想念的人就是远在纽约的小妹宋美龄。于是她托人捎信给宋美龄,希望姐妹二人能再团聚一次。宋家三姐妹在一起CRS23龙飞船我成功对接国际空间站,为航天员送去物资及设备在介绍CRS23任务前,先简单回顾一下SpaceX公司CRS22任务,还该任务发射是北京时间2021年6月4日凌晨1时29分左右,该任务发射地点为肯尼迪航天中心39A发射台,任务采陕西师大刘生忠教授团队在钙钛矿能源器件方面取得系列进展(1)在分子钙钛矿晶体的X射线探测器方面取得新进展近年来,分子钙钛矿在铁电压电非线性光学等领域已经发挥出了巨大的潜力,与传统的有机无机杂化钙钛矿相比,分子钙钛矿的形成不再依赖于有机拉尼娜指数持续下降到0。6,今年出现冷冬概率再次变大7月底开始,太平洋赤道地区的东部的海温就开始出现异常偏冷的趋势,平均海温已经从7月底跌破0到现在跌破到0。6,这说明太平洋东赤道地区的海洋出现较为剧烈的海水上翻运动导致温度较低的海