INNER
LEFT
RIGHT
FULL
OUTER
JOIN
merge
join
concat
update
… 和更多。我已经看到这些反复出现的问题询问熊猫合并功能的各个方面。今天,关于合并及其各种用例的大部分信息都分散在数十个措辞不当、无法搜索的帖子中。这里的目的是为后代整理一些更重要的观点。
本问答旨在成为有关常见 pandas 习语的一系列有用用户指南的下一部分
请注意,这篇文章 并不是 要替代文档,所以也请阅读!一些例子取自那里。
这篇文章旨在为读者提供 SQL 风格与 Pandas 合并的入门知识,如何使用它以及何时不使用它。
特别是,本文将介绍以下内容:
基础 - 连接类型(左、右、外、内)
这篇文章(以及我在这个线程上的其他帖子)不会经过:
注意 大多数示例在演示各种功能时默认为 INNER JOIN 操作,除非另有说明。 此外,这里的所有 DataFrame 都可以复制和复制,以便您可以使用它们。此外,请参阅这篇 关于如何从剪贴板读取 DataFrames 的帖子。 最后,JOIN 操作的所有视觉表示都是使用 Google 绘图手绘的。灵感来自这里。
注意 大多数示例在演示各种功能时默认为 INNER JOIN 操作,除非另有说明。
此外,这里的所有 DataFrame 都可以复制和复制,以便您可以使用它们。此外,请参阅这篇 关于如何从剪贴板读取 DataFrames 的帖子。
最后,JOIN 操作的所有视觉表示都是使用 Google 绘图手绘的。灵感来自这里。
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
为简单起见,键列具有相同的名称(目前)。
INNER JOIN 表示为
注意 这一点,以及即将到来的数字都遵循这个约定: 蓝色 表示合并结果中存在的行 红色 表示从结果中排除的行(即,已删除) 绿色 表示NaN在结果中用 s替换的缺失值
注意 这一点,以及即将到来的数字都遵循这个约定:
NaN
要执行 INNER JOIN,请调用merge左侧 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
这仅返回共享公共键的行(在此示例中为“B”和“D”)left。right
left
right
LEFT OUTER JOIN 或 LEFT JOIN 表示为
这可以通过指定来执行how='left'。
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 OUTER JOIN 或 RIGHT JOIN 是…
…指定how='right':
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 替换。
最后,对于 FULL OUTER JOIN ,由
指定how='outer'.
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。
该文档很好地总结了这些各种合并:
如果您需要 LEFT-Excluding JOIN 和 RIGHT-Excluding JOIN 分两步。
对于 LEFT-Excluding 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
在哪里,
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-Excluding 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,执行 ANTI-JOIN ),
你可以用类似的方式做到这一点——
(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有keyLeft,并且right有keyRight而不是——key那么你将不得不指定left_on和right_on作为参数而不是on:
keyLeft
keyRight
key
left_on
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
合并keyLeftfromleft和keyRightfromright时,如果您只需要输出中的一个keyLeft或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 操作时可能很重要。
left2.merge(right2, left_on='keyLeft', right_on='keyRight', how='inner')
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
如果您只需要合并“new_val”(没有任何其他列),您通常可以在合并之前只对列进行子集:
left.merge(right3[['key', 'newcol']], on='key') key value newcol 0 B 0.400157 0 1 D 2.240893 1
如果您正在执行 LEFT OUTER JOIN,则性能更高的解决方案将涉及map:
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(或left_on和right_on,视情况而定)指定一个列表。
left.merge(right, on=['key1', 'key2'] ...)
或者,如果名称不同,
left.merge(right, left_on=['lkey1', 'lkey2'], right_on=['rkey1', 'rkey2'])
merge*
将 DataFrame 与索引上的 Series 合并。
此外merge,DataFrame.update和DataFrame.combine_first在某些情况下还用于用另一个 DataFrame 更新一个 DataFrame。
DataFrame.update
DataFrame.combine_first
pd.merge_ordered是有序 JOIN 的有用函数。
pd.merge_ordered
pd.merge_asof(阅读:merge_asOf)对于 近似 连接很有用。
pd.merge_asof
本节仅涵盖最基本的内容,旨在激发您的胃口。 有关更多示例和案例,请参阅有关 、 和 的文档以及函数merge``join``concat规范的链接。
merge``join``concat