熊猫合并 101

2024-03-23

  • 我怎样才能执行(INNER| (LEFT|RIGHT|FULL) OUTER) JOIN和熊猫?
  • 合并后如何为缺失的行添加 NaN?
  • 合并后如何摆脱 NaN?
  • 我可以合并索引吗?
  • 如何合并多个 DataFrame?
  • 与 pandas 交叉连接
  • merge? join? concat? update? WHO?什么?为什么?!

... 和更多。我看到这些反复出现的问题询问 pandas 合并功能的各个方面。如今,有关合并及其各种用例的大多数信息都分散在数十个措辞糟糕、无法搜索的帖子中。这里的目的是为后代整理一些更重要的观点。

本问答旨在成为有关常见 Pandas 习语的一系列有用用户指南的下一部分(请参阅这篇关于旋转的文章 https://stackoverflow.com/questions/47152691/how-to-pivot-a-dataframe, and 这篇关于串联的文章 https://stackoverflow.com/questions/49620538/what-are-the-levels-keys-and-names-arguments-for-in-pandas-concat-functio,稍后我将谈到)。

请注意,这篇文章是not旨在替代文档 https://pandas.pydata.org/pandas-docs/stable/user_guide/merging.html,所以也请阅读该内容!一些示例取自那里。


目录

For ease of access.

  • 合并基础知识 - 连接的基本类型 https://stackoverflow.com/a/53645883/4909087(首先阅读此内容)

  • 基于索引的连接 https://stackoverflow.com/a/65167356/4909087

  • 泛化到多个 DataFrame https://stackoverflow.com/a/65167327/4909087

  • 交叉连接 https://stackoverflow.com/a/53699013/4909087


这篇文章旨在向读者介绍 SQL 风格的 Pandas 合并、如何使用它以及何时不使用它。

特别是,本文将介绍以下内容:

  • 基础知识 - 连接类型(LEFT、RIGHT、OUTER、INNER)

    • 与不同的列名称合并
    • 合并多列
    • 避免输出中出现重复的合并键列

这篇文章(以及我在该线程上的其他帖子)不会经历的内容:

  • 与性能相关的讨论和时间安排(目前)。在适当的情况下,主要提到了更好的替代方案。
  • 处理后缀、删除额外的列、重命名输出和其他特定用例。还有其他(阅读:更好)的帖子可以解决这个问题,所以弄清楚吧!

Note除非另有说明,大多数示例在演示各种功能时默认使用 INNER JOIN 操作。

此外,这里的所有 DataFrame 都可以复制和复制,因此 你可以和他们一起玩。另请参阅这 邮政 https://stackoverflow.com/questions/31610889/how-to-copy-paste-dataframe-from-stackoverflow-into-python关于如何从剪贴板读取数据帧。

最后,JOIN 操作的所有视觉表示都是使用 Google Drawings 手绘的。灵感来自here https://stackoverflow.com/a/55858991/4909087.



说得够多了——只是告诉我如何使用merge!

设置和基础知识

np.random.seed(0)
left = pd.DataFrame({'key': ['A', 'B', 'C', 'D'], 'value': np.random.randn(4)})
right = pd.DataFrame({'key': ['B', 'D', 'E', 'F'], 'value': np.random.randn(4)})

left

  key     value
0   A  1.764052
1   B  0.400157
2   C  0.978738
3   D  2.240893

right

  key     value
0   B  1.867558
1   D -0.977278
2   E  0.950088
3   F -0.151357

为了简单起见,键列具有相同的名称(目前)。

An 内部联接表示为

Note这个以及即将出现的数字都遵循这个约定:

  • blue表示合并结果中存在的行
  • red表示从结果中排除(即删除)的行
  • green表示缺失值被替换为NaN结果中的 s

要执行 INNER JOIN,请调用merge https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.merge.html在左侧 DataFrame 上,指定右侧 DataFrame 和连接键(至少)作为参数。

left.merge(right, on='key')
# Or, if you want to be explicit
# left.merge(right, on='key', how='inner')

  key   value_x   value_y
0   B  0.400157  1.867558
1   D  2.240893 -0.977278

这仅返回来自left and right它们共享一个公共密钥(在本例中为“B”和“D”)。

A 左外连接,或 LEFT JOIN 表示为

这可以通过指定来执行how='left'.

left.merge(right, on='key', how='left')

  key   value_x   value_y
0   A  1.764052       NaN
1   B  0.400157  1.867558
2   C  0.978738       NaN
3   D  2.240893 -0.977278

请仔细注意此处 NaN 的位置。如果您指定how='left',那么只有来自left已使用,并且缺少数据right被 NaN 取代。

同样,对于一个右外连接,或 RIGHT JOIN 这是...

...指定how='right':

left.merge(right, on='key', how='right')

  key   value_x   value_y
0   B  0.400157  1.867558
1   D  2.240893 -0.977278
2   E       NaN  0.950088
3   F       NaN -0.151357

在这里,钥匙来自right已使用,并且缺少数据left被 NaN 取代。

最后,对于全外连接,由下式给出

specify how='outer'.

left.merge(right, on='key', how='outer')

  key   value_x   value_y
0   A  1.764052       NaN
1   B  0.400157  1.867558
2   C  0.978738       NaN
3   D  2.240893 -0.977278
4   E       NaN  0.950088
5   F       NaN -0.151357

这使用了两个帧中的键,并且为两个帧中缺失的行插入了 NaN。

该文档很好地总结了这些不同的合并:


其他 JOIN - LEFT 排除、RIGHT 排除和 FULL 排除/ANTI JOIN

如果你需要LEFT-排除 JOIN and RIGHT-排除 JOIN分两步进行。

对于 LEFT-Exclusion JOIN,表示为

首先执行 LEFT OUTER JOIN,然后过滤来自left仅(不包括右侧的所有内容),

(left.merge(right, on='key', how='left', indicator=True)
     .query('_merge == "left_only"')
     .drop('_merge', 1))

  key   value_x  value_y
0   A  1.764052      NaN
2   C  0.978738      NaN

Where,

left.merge(right, on='key', how='left', indicator=True)

  key   value_x   value_y     _merge
0   A  1.764052       NaN  left_only
1   B  0.400157  1.867558       both
2   C  0.978738       NaN  left_only
3   D  2.240893 -0.977278       both

类似地,对于 RIGHT-Exclusion JOIN,

(left.merge(right, on='key', how='right', indicator=True)
     .query('_merge == "right_only"')
     .drop('_merge', 1))

  key  value_x   value_y
2   E      NaN  0.950088
3   F      NaN -0.151357

最后,如果您需要进行仅保留左侧或右侧键的合并,但不保留两者(IOW,执行反连接),

你可以用类似的方式做到这一点——

(left.merge(right, on='key', how='outer', indicator=True)
     .query('_merge != "both"')
     .drop('_merge', 1))

  key   value_x   value_y
0   A  1.764052       NaN
2   C  0.978738       NaN
4   E       NaN  0.950088
5   F       NaN -0.151357

关键列的不同名称

如果键列的名称不同 - 例如,left has keyLeft, and right has keyRight代替key——那么你必须指定left_on and right_on作为参数而不是on:

left2 = left.rename({'key':'keyLeft'}, axis=1)
right2 = right.rename({'key':'keyRight'}, axis=1)

left2

  keyLeft     value
0       A  1.764052
1       B  0.400157
2       C  0.978738
3       D  2.240893

right2

  keyRight     value
0        B  1.867558
1        D -0.977278
2        E  0.950088
3        F -0.151357
left2.merge(right2, left_on='keyLeft', right_on='keyRight', how='inner')

  keyLeft   value_x keyRight   value_y
0       B  0.400157        B  1.867558
1       D  2.240893        D -0.977278

避免输出中出现重复的键列

当合并时keyLeft from left and keyRight from right,如果您只想要其中一个keyLeft or keyRight(但不是两者)在输出中,您可以通过设置索引作为初步步骤开始。

left3 = left2.set_index('keyLeft')
left3.merge(right2, left_index=True, right_on='keyRight')

    value_x keyRight   value_y
0  0.400157        B  1.867558
1  2.240893        D -0.977278

将此与之前命令的输出进行对比(即,left2.merge(right2, left_on='keyLeft', right_on='keyRight', how='inner')),你会注意到keyLeft不见了。您可以根据将哪个帧的索引设置为键来确定要保留哪一列。例如,当执行某些 OUTER JOIN 操作时,这可能很重要。


仅合并其中一列中的一列DataFrames

例如,考虑

right3 = right.assign(newcol=np.arange(len(right)))
right3
  key     value  newcol
0   B  1.867558       0
1   D -0.977278       1
2   E  0.950088       2
3   F -0.151357       3

如果您需要仅合并“newcol”(没有任何其他列),通常可以在合并之前对列进行子集化:

left.merge(right3[['key', 'newcol']], on='key')

  key     value  newcol
0   B  0.400157       0
1   D  2.240893       1

如果您正在进行 LEFT OUTER JOIN,则性能更高的解决方案将涉及map:

# left['newcol'] = left['key'].map(right3.set_index('key')['newcol']))
left.assign(newcol=left['key'].map(right3.set_index('key')['newcol']))

  key     value  newcol
0   A  1.764052     NaN
1   B  0.400157     0.0
2   C  0.978738     NaN
3   D  2.240893     1.0

如前所述,这类似于但比

left.merge(right3[['key', 'newcol']], on='key', how='left')

  key     value  newcol
0   A  1.764052     NaN
1   B  0.400157     0.0
2   C  0.978738     NaN
3   D  2.240893     1.0

合并多列

要加入多个列,请指定一个列表on (or left_on and right_on, 作为适当的)。

left.merge(right, on=['key1', 'key2'] ...)

或者,如果名称不同,

left.merge(right, left_on=['lkey1', 'lkey2'], right_on=['rkey1', 'rkey2'])

其他有用的merge*操作和功能

  • 将 DataFrame 与索引上的 Series 合并:请参阅这个答案 https://stackoverflow.com/a/40762674/4909087.

  • Besides merge, DataFrame.update https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.update.html and DataFrame.combine_first https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.combine_first.html在某些情况下也用于用另一个 DataFrame 更新一个 DataFrame。

  • pd.merge_ordered http://pandas.pydata.org/pandas-docs/version/0.19.0/generated/pandas.merge_ordered.html对于有序 JOIN 来说是一个有用的函数。

  • pd.merge_asof https://pandas.pydata.org/pandas-docs/stable/generated/pandas.merge_asof.html(阅读:merge_asOf)对于近似 joins.

本节仅涵盖非常基础的内容,旨在激发您的兴趣。更多示例和案例请参见文档关于merge, join, and concat https://pandas.pydata.org/pandas-docs/stable/merging.html以及功能规格的链接。



继续阅读

跳转到 Pandas Merging 101 中的其他主题继续学习:

  • Merging basics - basic types of joins https://stackoverflow.com/a/53645883/4909087 *

  • 基于索引的连接 https://stackoverflow.com/a/65167356/4909087

  • 泛化到多个 DataFrame https://stackoverflow.com/a/65167327/4909087

  • 交叉连接 https://stackoverflow.com/a/53699013/4909087

*You are here.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

熊猫合并 101 的相关文章

随机推荐

  • 返回修改后的类和使用 type() 之间的区别

    我想这更像是一个 python 问题 而不是 django 问题 但我无法在其他地方复制这种行为 所以我将使用无法按预期工作的确切代码 当我发现这个工厂函数片段时 我正在 django 中处理一些动态表单 def get employee
  • GitHub Copilot - 请登录 github 并重试

    对于 Intellij 插件 GitHub Copilot 显示错误please login to github and try again 我已经完成了以下操作 使用我的 GitHub 用户和密码对 GitHub Copilot 进行了身
  • Swift UITableViewCell 对齐

    我正在尝试显示如下页面 页面标题 左对齐 区域名称 中心对齐 该地区的人 详细标签中带有电子邮件的副标题 但是 如果我选择副标题作为单元格样式 则所有内容都将左对齐 并且我无法在代码中更改它们 然后 如果我选择自定义作为样式 则详细文本标签
  • 当尝试在 R 中运行 kNN 时,我收到由 coercionNAs 引入的错误 NAs?

    我正在尝试在数据集上运行 kNN 但我不断收到一些 NA 错误 我已经用尽了堆栈溢出试图找到这个问题的解决方案 我在任何地方都找不到任何有用的东西 这是我正在使用的数据集 https www kaggle com tsiaras uk ro
  • java.util.Vector - 替代品

    以前 当长度未知时 我一直认为 Vector 适合用于非描述性对象 据我所知 我认为它也是线程安全的 什么会改变这一点Vector不应再使用 有什么替代方案 你应该使用ArrayList代替Vector Vector使用内部同步 但这对于实
  • Android - 如何拦截“安装应用程序”意图

    好吧 所以不完全确定这是可能的 但尝试编写一个应用程序 以便我可以在执行以下任何活动之前运行一些代码 1 从网络下载 APK 并启动安装程序 2 在android市场上按下安装按钮 是否有可能拦截并提示这些事件 或者谷歌已经将这些东西锁定得
  • 如何在 css URL 中使用相对/绝对路径?

    我有一个生产和开发服务器 问题是目录结构 发展 http dev com subdir images image jpg http dev com subdir resources css style css 生产 http live co
  • 通过进程 ID 将 KeyEvent 发送到目标窗口

    我需要创建一个关键事件 cmd r 用于刷新浏览器窗口 并传递我尝试定位的窗口的进程 ID 比方说 let customEvent NSEvent keyEvent with NSEvent EventType keyUp location
  • 表达式集子集化

    我有一个ExpressionSet我想要子集的对象 例如 gt str ESet Formal class ExpressionSet package Biobase assayData phenoData STATUS num 1 210
  • 在python中将JSON存储到数据库中

    我定期从 API 获取一些数据 并希望将 JSON 数据存储到数据库中以便稍后访问和使用 从 API 中 我每次都会获取此样本中的数据 data cursor null files nodes u code u BOPhmYQg5Vm u
  • CLLocation距离位置(在Swift中?)

    有人可以帮我将以下 Objective C 语句转换为 Swift 吗 CLLocationDistance distance fromLocation distanceFromLocation toLocation 我知道做到这一点一定很
  • 标准库类型的赋值运算符的 ref 限定符

    我想知道 标准类型的赋值运算符没有左值引用限定是否有原因 他们都不是 因此 我们可以这样写 std string 42 std string s hello std string world oops std vector
  • 在jgit中配置known_hosts

    使用 jgit 和 gitolite 进行源代码控制 我有一个应用程序 可以根据命令生成某些代码 并且我们希望将其提交给源代码控制 目标是快速拉动 提交新代码 然后推送它 我有以下方法 private void commitToGitRep
  • 为什么 ISO/IEC 对 C 和 C++ 标准收费而不是免费提供?

    ISO C 标准 ISO IEC 9899 和 ISO C 标准 ISO IEC 14882 未在线发布 相反 人们必须购买每一项标准的 PDF 版本 我想知道这背后的基本原理是什么 对于 C 和 C 编程语言来说 这些语言的权威规范不能免
  • 静态 constexpr 类成员何时需要类外定义?

    我有以下 C 11 代码 简化版本 struct Info const char name int version class Base public const Info info Base Info info info info cla
  • Xaringan 幻灯片上的目录?

    我想知道是否可以将显示目录的幻灯片添加到使用 xaringan 包创建的文档中 谢谢 Update 以下几行将为您提供自动大纲 不幸的是 我不知道如何在 RStudio 中自动重新加载 R 脚本文件 如果有人知道什么 请随时在下面评论或回答
  • 如何将 Windows Update 设置为从不使用 PowerShell 检查更新?

    我正在寻找使用 PowerShell Windows Server 2008 R2 编写脚本的帮助 因此 Windows 更新设置为 从不检查更新 我找到了一些接近的答案 但我仍然无法做我想做的事 目前 我必须通过单击 Windows 更新
  • JQuery 对话框作为输入

    我不太习惯使用 jquery 对话框之类的东西 所以这是一个新手问题 此时 我正在使用提示来获取 SharePoint 中用户的回复 var answer dialog Type the text you want to display i
  • 使用 Spring RestTemplate 将嵌套 JSON 对象映射到 Java 类

    我知道这可能很简单 但是 我就是无法让它发挥作用 所以我尝试使用 Spring RestTemplate 来映射我的 JSON 数据 我有以下来自休息调用的 JSON 响应 message ok status ok data Name Yo
  • 熊猫合并 101

    我怎样才能执行 INNER LEFT RIGHT FULL OUTER JOIN和熊猫 合并后如何为缺失的行添加 NaN 合并后如何摆脱 NaN 我可以合并索引吗 如何合并多个 DataFrame 与 pandas 交叉连接 merge j