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

错得离谱!竟然说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新版本增强功能,数据表多列频率统计

韩国第一网红孙允珠的精美写真集一孙允珠是韩国的一个美女模特,样貌身材极佳。孙允珠1992年5月7日出生在韩国首尔特别市,身高167cm,体重49kg,最大的爱好是做日本料理!孙允珠是韩国网红,颜值和身材都是非常出杉原杏璃时隔6年拍摄写真集,直言无法回到过去演员杉原杏璃于1月29日,在暌违6年半的写真集发售纪念活动前举行了采访会,就40岁挑战写真拍摄谈到了自己的辛苦。2010年代作为写真偶像风靡一时的杉原。2017年35岁的她停止了写黔江机场将新开合肥黔江拉萨航线乘坐飞机的市民注意啦!今(26)日起,黔江机场开始执行2023年夏航季航班计划,将携手西部航空新开合肥黔江拉萨航线。此次新开合肥黔江拉萨航线10点25分从合肥新桥国际机场出发,12AI绘画美学之七,和你的白衣学妹去森林中的探险春天是一个充满生机的季节,也是踏青的好时节。踏青,就是走遍山野,感受大自然的美好。这是一种享受生活放松心情的方式。踏青的路途中,一路都是绿色的世界。在山间小路上,有着各种各样的花草普尔追梦再打拳,勇士输球后更衣室爆发矛盾,内讧勇士能走多远?北京时间3月29日星期三美媒记者比尔西蒙斯爆料,勇士再之前客场迎战森林狼输球后球员回归更衣室之后追梦格林和乔丹普尔再次爆发冲突,好在球队球员及时出手把两人分开终止了此次冲突。而两人当你有这种难隐之言,千万别忍着在日常生活中,不少人或多或少有便秘的困扰。数据显示,全球有近15亿人遭受便秘的困扰,其中女性发病率约是男性的2倍,老年人发病率是年轻人的5倍。今天(3月28日)是中国便秘日,这种难姚迪围观与姚迪接近完成签约的费内巴切费内巴切女排俱乐部,位于土耳其伊斯坦布尔,成立于1954年,曾在分别在2010年及2011年夺得世界女排俱乐部锦标赛及欧洲女排冠军联赛冠军,而在土耳其女排联赛则收获5次冠军,为现时GTA5卡在进入画面GTA5进不去游戏最新解决方法GTA5支持最多30名玩家同台在线游玩,玩法超丰富,受到很多玩家的喜爱。在GTA5中,玩家们可以成为想成为的人,例如商业大亨,超多GTA游戏币让玩家们尽情挥霍,享受土豪人生。有不少奥斯梅恩或将创造历史,球员或将收获双向荣誉威廉希尔奥斯梅恩或将创造历史,球员或将收获双向荣誉根据意甲媒体报告,如果那不勒斯最终能够在本赛季的意甲联赛捧杯,球对前锋奥斯梅恩在拿到意甲冠军的同时,另一边可以收获联赛最佳射手的荣ChatGPT推荐中国最合适旅游城市排行榜中国作为一个拥有悠久历史和丰富多样的文化的国家,有很多值得一游的城市。以下是我为您推荐的10个最合适旅游的城市以及它们的深度分析1。北京作为中国的首都,北京拥有许多著名的历史遗迹和七八十年代,几乎每人肚子里都有蛔虫,为啥现在没人感染蛔虫了?在七八十年代,几乎每个人肚子里都曾经生过蛔虫,这是很普遍的现象。然而,现在的人却很少感染蛔虫了,这是为什么呢?首先,现代人的饮食习惯已经发生了很大的变化。现代人更加注重饮食的卫生和
詹姆斯本场禁赛,威少空砍31分13篮板10助攻,他在第三节独得18分看慢动作回放就知道,詹是故意的,先是转头瞥了再出手的,也就是出手动作发生在转头动作之后。选择在场上的任意一位球员作为代入,甚至可以感受到球员心跳的冲撞的360度体验,哪个球员体验率一夜消息萧华宣布事项,老詹即将上演决定四,希望之星令人唏嘘北京时间2月20日,在过去的一夜中,nba传来了3条消息,一起来看看吧。萧华宣布事项今日,nba总裁亚当萧华召开了新闻发布会,期间他回答了多个问题。在谈到明天即将在2022克利夫兰2月20日早读你不能错过的新闻都在这里牵手十五载葱桶将最好的自己留到家门口2月19日晚,北京冬奥会花样滑冰双人滑金牌在首都体育馆产生。两届世锦赛冠军平昌奥运会银牌得主隋文静韩聪在自由滑比赛中,完美演绎忧伤河上的金桥,表巴黎13,揪出混子巨星!点球不进,沉迷场外,金球奖彻底无望大巴黎在今日的法甲比赛中爆冷13输给了南特。球队在经历了和皇马的大战之后仿佛放松了警惕,回归法甲开始休闲模式。比赛中大巴黎的锋线混子巨星也是成为了球迷们批评的对象,姆巴佩在突破到禁世界体坛很难突破的5个记录,博尔特的9秒58毫无意外上榜前言从世界各国开始交流和沟通,到现在已经很多年了,在这么多年间除了文化方面以及经济方面有交集之外,在体育这一块儿,世界上公认的都对于自己国人的身体素质非常关注,因为国人身体素质好的创历史!中国冬奥金牌九宫格截至2月19日中国体育代表团在北京冬奥会上收获9枚金牌!再次回顾超燃瞬间来源中国新闻社统筹段磊校对张臻一读王文艳初审张翼段磊终审阿拉腾声明未经授权,禁止转载使用本公众号原创文章。转官方为吴曦庆祝33岁生日,醉卧沙场君莫笑,古来征战几人回02月19日,今天是中国男足队长吴曦的33岁生日,中国足球队官方也送上了生日祝福。国足官方微博写道22岁,世预赛对阵老挝队,翩翩少年,初登洲际赛场26岁,亚洲杯对阵乌兹别克斯坦队,孙卓回老家后变化大,跟孙辉抢活引热议,孙悦回应叫人心生佩服冬奥会的到来,给教育领域带来不小的改变,以前家长人认为文化课成绩好才是真的好,现在家长们已经不这么认为了,一名学生的全员面发展不仅仅有文化课一方面,还需要有强健的体魄,以及德智体美奥运精准计时的背景,至今已有90年历史北京2022年冬奥会期间,赞助的企业品牌形象一如既往地突出可口可乐英特尔爱彼迎Visa丰田中国银行三星等全球性品牌。其中有一个品牌在每场比赛起着关键作用,它的精准计时决定每场比赛的队史第一人,场均32。5分!老詹头还得继续扛大旗老詹头又创新高了上一战梦碎盐湖城之后(眉眉伤退),老詹头力挽狂澜,上演了一波单骑救主的好戏,单节狂揽15分,全场33分,外加8板6助2断。此役战过后,老詹头已经连续23场比赛得分超颤抖吧,最强快船要回来了!乔治释放的信号不简单,佩林卡学着点不知不觉中,NBA常规赛已经走完了三分之二的赛程,接下来就是为期一周的全明星周末,全明星结束之后,各支球队将会为自己的季后赛席位开启最后的冲刺。今天我们来聊聊快船队,近三个赛季,快