如何执行与pandas(LEFT| RIGHT| FULL)(INNER| OUTER)的联接?
合并后如何为缺失的行添加NaN?
合并后如何去除NaN?
我可以合并索引吗?
与pandas交会吗?
如何合并多个DataFrame?
merge?join?concat?update?Who? What? Why?!
… 和更多。我已经看到这些重复出现的问题,询问有关熊猫合并功能的各个方面。有关合并及其各种用例的大多数信息都分散在数十个措辞不好,无法搜索的帖子中。这里的目的是整理后代的一些更重要的观点。
这篇文章旨在为读者提供有关SQL风格的与pandas的合并,使用方法以及何时不使用它的入门。
特别是,这是这篇文章的内容:
基础知识-联接类型(左,右,外,内)
与不同的列名合并
这篇文章不会讲的内容:
与性能相关的讨论和时间安排(目前)。在适当的地方,最引人注目的是提到更好的替代方案。
处理后缀,删除多余的列,重命名输出以及其他特定用例。还有其他(阅读:更好)的帖子可以解决这个问题,所以请弄清楚!
注意
除非另有说明,否则大多数示例在演示各种功能时会默认使用INNER JOIN操作。
此外,可以复制和复制此处的所有DataFrame,以便您可以使用它们。另外,请参阅这篇文章 ,了解如何从剪贴板读取DataFrame。
最后,所有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,请调用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
这仅返回来自left
并right
共享一个公共密钥的行(在此示例中为“ B”和“ D”)。
甲LEFT OUTER JOIN,或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使用from 的键,而缺失的数据right被NaN替换。
同样,对于RIGHT OUTER JOIN或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使用了from 的键,而缺失的数据left被NaN代替。
最后,对于FULL OUTER JOIN,由
指定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排除联接和RIGHT排除联接。
对于不包括JOIN的LEFT,表示为
首先执行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
同样,对于除权利加入之外,
(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
has keyLeft
和right
has 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
在keyLeftfrom left和keyRightfrom 上进行合并时right,如果只希望输出中的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操作时,这可能很重要。
例如,考虑
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
如果您要进行左外部联接,则性能更高的解决方案将涉及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.update和DataFrame.combine_first也用在某些情况下,更新一个数据帧与另一个。
pd.merge_ordered 对有序的JOIN是有用的函数。
pd.merge_asof(阅读:merge_asOf)对于近似联接很有用。
问题内容: 我有一个带有4列的(example-)数据框: 我现在想将B,C和D列合并/合并到新的E列,如本例所示: 我在这里发现了一个非常类似的问题,但这在A列的末尾添加了合并的列B,C和D: 感谢帮助。 问题答案: 选项1 使用和 选项2 使用分配和 选项3 最近,我喜欢第3个选项。 使用
主要内容:使用how参数合并Pandas 提供的 merge() 函数能够进行高效的合并操作,这与 SQL 关系型数据库的 MERGE 用法非常相似。从字面意思上不难理解,merge 翻译为“合并”,指的是将两个 DataFrame 数据表按照指定的规则进行连接,最后拼接成一个新的 DataFrame 数据表。 merge() 函数的法格式如下: pd.merge(left, right, how='inner', on=
问题内容: 我正在使用下面的代码合并两个csv(数据帧): 我有以下CSV文件 文件1: 文件2: 合并后 如果您注意到student_id的开头附加了0,应该将其视为文本,但是在合并并使用函数后,它将其转换为数字并删除了前导0。 即使在to_csv之后,如何将列保持为“文本”? 我认为它的to_csv函数可以再次保存为数字添加了dtype = {‘student_id’:str}。 问题答案:
问题内容: 有很多类似的问题,但没有一个专门针对此问题。 我有一个数据帧列表,我需要使用唯一列将它们合并在一起。字段名称不同,因此concat退出了。 我可以手动使用等将每个df逐一合并,但是问题是列表中数据帧的数量随用户输入而不同。 有什么合并方法可以一次性将所有数据帧合并到一个列表中?还是某些for in loop? 我正在使用Python 2.7。 问题答案: 您可以使用函数where是数据
In[1]: import pandas as pd import numpy as np import matplotlib.pyplot as plt %matplotlib inline 1. DataFrame添加新的行 # 读取names数据集 In[2]: names = pd.read_csv('data/names.csv')
问题内容: 可以说我有一个DataFrame如下: 我想创建一个新的DataFrame像这样: 可能的代码是什么? 问题答案: 1.使用Python 3.6+更新,使用带有列表理解功能的f字符串格式: 2.使用和: 3.如果您的列具有数字数据类型,请使用和: 输出: