- 如何执行(
INNER
|(LEFT
)|RIGHT
|有Pandas吗? - 如何在合并后为缺少的行添加NaN?
- 如何在合并后删除NaN?
- 我可以在索引上合并吗?
- 如何合并多个DataFrame?
- 与Pandas交叉连接
- 谁?什么?为什么?
......还有更多。我看到这些反复出现的问题询问Pandas合并功能的各个方面。今天关于合并及其各种用例的大部分信息都分散在几十个措辞糟糕、无法搜索的帖子中。这里的目的是为后代整理一些更重要的观点。
这篇问答文章将是一系列关于Pandas常用习语的实用用户指南的下一篇文章(参见this post on pivoting和this post on concatenation,我稍后会谈到)。
请注意,这篇文章 * 不是 * 要取代the documentation,所以请也阅读这篇文章!
目录
为了方便访问。
8条答案
按热度按时间3okqufwl1#
这篇文章旨在给予读者一个入门的SQL风格的合并与Pandas,如何使用它,什么时候不使用它。
具体来说,这篇文章将经历以下内容:
这篇文章(和其他职位由我在这个线程)不会经历:
注意除非另有说明,否则在演示各种功能时,大多数示例都默认使用INNER JOIN操作。
此外,这里所有的DataFrame都可以被复制和复制,这样你就可以玩它们了。另外,关于如何从剪贴板读取DataFrame,请参阅this post。
最后,JOIN操作的所有可视化表示都是使用Google Drawings手工绘制的。
说得够多了-告诉我如何使用
merge
!设置和基础知识
为了简单起见,键列具有相同的名称(目前)。
INNER JOIN表示为
注这一点沿着随后的数字均遵循以下惯例:
*蓝色表示合并结果中存在的行
*红色表示从结果中排除(即删除)的行
*绿色表示结果中替换为
NaN
s的缺失值若要执行INNER JOIN,请在左侧DataFrame上调用
merge
,并将右侧DataFrame和联接键(至少)指定为参数。这只会传回
left
和right
中共用相同索引键的数据列(在此范例中为“B”和“D”)。左外部联接或左联接表示为
这可以通过指定
how='left'
来执行。注意NaN的位置,如果指定
how='left'
,则只使用left
中的键,right
中缺少的数据将被NaN替换。类似地,对于右外部联接或右联接...
...指定
how='right'
:这里,使用来自
right
的密钥,并且用NaN替换来自left
的缺失数据。最后,对于FULL OUTER JOIN,由下式给出
请指定
how='outer'
。这将使用两个帧中的关键点,并为两个帧中缺少的行插入NaN。
该文档很好地总结了这些不同的合并:
x1c4d 1x指令集
其他联接-左排除、右排除和完全排除/反联接
如果您需要分两步执行左排除联接和右排除联接。
对于左排除JOIN,表示为
首先执行LEFT OUTER JOIN,然后只筛选来自
left
的行(排除右侧的所有行),其中:
类似地,对于右排除联接,
最后,如果您需要执行一个只保留左边或右边的键而不是两者的合并(IOW,执行ANTI-JOIN),
你可以用类似的方法-
键列的不同名称
如果键列的名称不同(例如,
left
的名称为keyLeft
,right
的名称为keyRight
而不是key
),则必须指定left_on
和right_on
作为参数,而不是on
:避免在输出中出现重复的键列
在合并
left
中的keyLeft
和right
中的keyRight
时,如果您只希望输出中包含keyLeft
或keyRight
中的一个(而不是两个),则可以首先设置索引作为预备步骤。与之前的命令输出(即
left2.merge(right2, left_on='keyLeft', right_on='keyRight', how='inner')
的输出)相比,您会注意到keyLeft
丢失了。您可以根据哪个帧的索引被设置为键来确定要保留哪一列。这在执行某些OUTER JOIN操作时可能很重要。**仅合并
DataFrames
**之一的单个列例如,考虑
如果只需要合并“newcol”(不合并任何其他列),通常可以在合并之前只合并子集列:
如果您正在执行LEFT OUTER JOIN,则性能更高的解决方案将涉及
map
:如前所述,这与类似,但比更快
合并多个列
若要联接多个列,请为
on
(或left_on
和right_on
,视情况而定)指定一个列表。或者,在名称不同的情况下,
型
其他有用的
merge*
操作和函数merge
之外,DataFrame.update
和DataFrame.combine_first
也在某些情况下用于将一个DataFrame更新为另一个DataFrame。pd.merge_ordered
是用于有序JOIN的有用函数。pd.merge_asof
(读取:merge_asOf)对于 * 近似 * 连接非常有用。本节只介绍最基本的内容,旨在激发您的兴趣。有关更多示例和案例,请参阅documentation on
merge
,join
, andconcat
以及指向函数规范的链接。继续阅读
跳转到Pandas Merging 101中的其他主题继续学习:
qxgroojn2#
pd.concat([df0, df1], kwargs)
的补充可视视图。请注意,kwargaxis=0
或axis=1
的含义不如df.mean()
或df.apply(func)
直观arknldoa3#
联接101
这些动画可能会更好地解释你的视觉效果。Garrick Aden-Buie tidyexplain repo
内部链接
外部联接或完全联接
右连接
左连接
5n0oy7gb4#
在回答这个问题时,我将考虑以下实际例子:
pandas.concat
pandas.DataFrame.merge
以合并来自一个索引的 Dataframe 和另一个索引的列的 Dataframe 。我们将对每种情况使用不同的 Dataframe 。
1.
pandas.concat
*********考虑以下具有相同列名的
DataFrames
:*2018年价格,尺寸为
(8784, 5)
*2019年价格,尺寸为
(8760, 5)
可以使用
pandas.concat
将它们组合起来,只需这会产生大小为
(17544, 5)
的DataFrame如果一个人想清楚地了解所发生的事情,它是这样工作的
(Source)
2.
pandas.DataFrame.merge
的文件在本节中,我们将考虑一个具体的案例:合并一个 Dataframe 的索引和另一个 Dataframe 的列。
假设 Dataframe
Geo
包含54
列,Date
是datetime64[ns]
类型的列之一。Dataframe
Price
中有一列的价格名为Price
,索引对应于日期(Date
)为了合并它们,可以如下使用
pandas.DataFrame.merge
其中
Geo
和Price
是先前的 Dataframe 。这将产生以下 Dataframe
pbpqsu0x5#
这篇文章将讨论以下主题:
merge
、join
、concat
BACK TO TOP
基于索引的联接
TL;DR的名称
有几个选项,有些比其他更简单,这取决于用例。
left_index
和right_index
的DataFrame.merge
(或使用命名索引的left_on
和right_on
)DataFrame.join
(索引上的联接)pd.concat
(索引上的连接)索引到索引连接
设置与基础
通常,索引上的内部连接如下所示:
其他连接遵循类似的语法。
值得注意的替代方案
1.**
DataFrame.join
**默认为索引上的联接。DataFrame.join
默认执行左外部联接,因此此处需要how='inner'
。请注意,我需要指定
lsuffix
和rsuffix
参数,因为join
否则会出错:因为列名称相同。如果它们的名称不同,这不会是问题。
1.**
pd.concat
**在索引上进行联接,并且可以一次联接两个或多个DataFrame。默认情况下,它执行完全外部联接,因此此处需要how='inner'
。有关
concat
的更多信息,请参阅此帖子。列连接的索引
要使用左索引、右列执行内部连接,您将使用
DataFrame.merge
(left_index=True
和right_on=...
的组合)。其他联接遵循类似的结构。请注意,只有
merge
可以执行索引到列的联接。如果左侧的索引级别数等于右侧的列数,则可以联接多个列。join
与concat
不能进行混合合并.您需要使用DataFrame.set_index
将索引设置为预处理步骤.有效使用命名索引[pandas〉= 0.23]
如果你的索引是命名的,那么从pandas〉= 0.23开始,
DataFrame.merge
允许你将索引名称指定为on
(或者根据需要指定为left_on
和right_on
)。对于前面的合并示例,索引为left,列为right,可以使用索引名称为left的
left_on
:继续阅读
跳转到Pandas Merging 101中的其他主题继续学习:
yhived7q6#
这篇文章将讨论以下主题:
merge
在这里有缺点)BACK TO TOP
泛化为多个DataFrame
通常,当多个DataFrame要合并在一起时会出现这种情况。简单地说,这可以通过链接
merge
调用来完成:然而,对于许多 Dataframe 来说,这很快就失去了控制。此外,可能需要对未知数量的 Dataframe 进行归纳。
这里我将介绍
pd.concat
和DataFrame.join
,前者用于 unique 键上的多路连接,后者用于 non-unique 键上的多路连接。对唯一键进行多路合并
如果键(这里的键可以是列或索引)是唯一的,则可以使用
pd.concat
。请注意,pd.concat
在索引上联接DataFrame。对于FULL OUTER JOIN,省略
join='inner'
。请注意,不能指定LEFT或RIGHT OUTER联接(如果需要,请使用join
,如下所述)。对具有重复项的键进行多路合并
concat
速度很快,但也有缺点,它不能处理重复项。第一个
在这种情况下,我们可以使用
join
,因为它可以处理非唯一键(注意,join
在DataFrame的索引上连接DataFrame;除非另外指定,否则它将秘密调用merge
并执行LEFT OUTER JOIN)。继续阅读
跳转到Pandas Merging 101中的其他主题继续学习:
ecr0jaav7#
我认为你应该在解释中包括这个,因为这是一个我经常看到的相关合并,我相信它被称为
cross-join
。这是一个当唯一的df不共享列时发生的合并,它只是将2个df并排合并:设置:
这将创建一个虚拟的X列,在X上合并,然后删除它以生成
df_merged:
2ekbmq328#
Pandas目前不支持合并语法中的不等连接;一个选项是使用pyjanitor中的conditional_join函数-我是这个库的贡献者:
列作为元组的变量参数传递,每个元组由左 Dataframe 中的一列、右 Dataframe 中的一列和联接运算符(可以是
(>, <, >=, <=, !=)
中的任何一个)组成。在上面的示例中,由于列名重叠,因此返回了MultiIndex列。从性能上看,这比单纯的交叉连接要好: