融合数据 Concat 和 Merge

融合数据 Concat 和 Merge

作者: 莫烦 编辑: 莫烦 发布于: 2022-03-13

数据表合并的情况也不罕见,在工作学习中,肯定有需要把表合并处理的时候,比如每个班级收上来一份班级表, 年级主任需要把所有班级表合并,在统一看全年级的情况。我们今天就来见识 Pandas 里面用于合并的多样化处理方式。

日常要处理的合并情况还是相对比较简单的,但是 Pandas 提供了非常丰富的合并方案,我觉得也没必要介绍那些偏门的, 先提前知晓,下面的内容是针对我们生活中比较常见的情况,如果下面的方法不能满足你的需求, 可以来看看这份官方文档

本节要涉及的功能:

concat

介绍

最简单的拼接无非就是上下左右的拼接,但是你有没有想过,在 Pandas 的 DataFrame 中,我们还有 index 和 column 这东西的存在, 它们的存在是为了我们更好的对应上数据的 index,可以用这些 index 索引和选取数据。

那么在拼接的时候,你无时无刻也要关注对齐的影响。我们需不需要让 index 和 column 对齐,如果对不齐,有能怎么办? 还好 Pandas 早为你想到了这些问题,也提供了很多合适的处理方案。

拼接Concat

注意,我都规定了这三组 df 拥有不相冲突的 index,但是相同的 column 名,我们把它们进行上下拼接看看。

concat

假设上面是三个不同班级的学生信息,如果你还是想带上班级的索引栏,你可以给他们加上一个主 key。比如 xyz 三个不同班。

keys

这样你索引的时候,还是可以按班级来索引。这样可以既不破坏原本的 df 结构,又不丢失不同 df 的组织状态。

pd.concat 的默认是上下拼接的,我们也可以指定进行左右拼接。

注意,我这里故意没有对齐他们的 index。 你仔细观察的话,df1df4 不是完全标齐的 index 和 column, 但是他们还是可以拼接的,只是拼接的时候 pandas 会自动将缺失的部分填充成 NaN。

axis1

其实这种模式叫做 join="outer" 的方式(默认方式), 中文的话,就叫它外拼接吧。与其对应的,只留下对齐后的 index 和 column 模式, 我们可以用内拼接 join="inner"

inner

有内外拼接,说明你十分关注重组后的数据 index,但是有的时候,我们的确不会关注新数据的 index 对齐。 与其保留老数据的索引,我还不如搞一个全新索引,直接覆盖了,不管以前了。用 ignore_index 就可以。

ignore_index

之前讲 pandas DataFrame 结构基础操作的时候. 同学们可能会有这样一个疑问,我们怎么像 Numpy 或者 Python List 那样,append 数据进来呢?那这节数据拼接内容就来告诉你,可以用 concat

我把一条新的 col X 数据拼接到了 df1 的最右边。同样,如果你要向下 append 的话,首先你要有一条对应的 Series 数据。 然后 pd.concat 时选用 axis=0 进行上下拼接。但是 Pandas 不会帮你自动判断 添加 Series 的维度信息。这里还需要你手动将 Series 转化 .to_frame() 成 df,并调整 df 的维度信息,才能正常拼接。

as row

做一个类似 Python list append 的操作这么麻烦的吗!! 当然不是,你也可以用一个简单的 append 搞定。两者出来是一样的效果。

pd.concat() 我觉得已经能满足我们日常生活中的大部分拼接任务了。不过 Pandas 知道你肯定还有特殊需求, 比如在拼接的时候,到底要基于哪边 df 的 index?要不要添加特殊的新 col 名等等。所以它还给了一个更加细节的 pd.merge() 函数。

融合Merge

一般来说,如果你十分熟悉 SQL 语言那一套,merge 就非常适合你,其他的小伙伴,我觉得只有你发现 concat 不能解决你的问题的时候, 在过来看看 merge 能不能。因为 merge 还是比 concat 稍微复杂一点的。比如光是 join 的方式,就比 concat 多出了 3 种。

注意,concat 可以一次性合并多个 df,可以【左右】,也可以【上下】拼接, 但是 merge 是用来针对两张 df 做【左右】拼接的。 但是如果你真的懂 merge 的功能,也许你会更喜欢用 merge

重要的事说三遍,merge 只做左右拼接。左右拼接。左右拼接。

merge on key

另外一点注意的:merge() 只在你指定的 col 作为 index 来合并,所以有一个 on="key" 参数。 而 concat 只在 index/column 上寻找统一索引。 merge()concat() 在用法上,的确是有很大差别的。

上面只在对齐的时候基于了一个 key,如果你的数据中还有多个可以用个 key column, 你也可以传入所有你想要基于的 key 做拼接 on=["key1", "key2"]

对比 concat(), 我前面也提到,merge() 在 join 的时候,方法比 concat() 多了 3 种。 下面的前两种是 concat()merge() 都具备的。后面几种是 merge() 另外的。

  1. outer: 集合两个 df 所有 的 key
  2. inner: 集合两个 df 同时拥有 的 key
  3. left: 仅考虑左边 df 所有 的 key
  4. right: 仅考虑右边 df 所有 的 key
  5. cross: 对于两个 df key 的笛卡尔积

left

你在上面的 how 中填入不同的值,来试试看不同的结合效果。我在下面贴几张图,用来演示这几种不同的效果。

right

right

outer

right

inner

right

cross

cross 比较特别,组出来的表特别大,因为它是两个 key 的笛卡尔积,一般其实你也用不到。

right

merge 我就先介绍到这里,还有一些其他的参数,比如 suffixes,indicator。如果你感兴趣, 可以看到这份官方文档

接入Join

明白了 merge,我就可以来说说 join 了。join 其实是 df.join()。 但是它其实更像是 mergeconcat 的某种结合体,merge() 是基于给定的某个 on="key" 来拼接, 而 df.join() 使用的 key 可以和 concat() 一样,都是 index,也可以像 merge() 带一个 on="key" 去使用一个 column 作为索引。

join

df.join() 的时候默认是使用 how="left" 的。你可以在上面尝试将 how 这个参数明确出来,写不同的 join 方式, 比如 ‘left’, ‘right’, ‘outer’, ‘inner’

使用 key 作为 join 依据的时候,你可以这样使用:

key

总结

今天我向大家介绍了三种 pandas 中常用来合并数据的方式,concatmergejoin 他们的规则还是挺多的, 我也挑了一些重要的来讲解,如果你发现上面的合并方式还不能解决你的问题, 我将文档也贴上,你可以查看一下官方的说明


降低知识传递的门槛

莫烦经常从互联网上学习知识,开源分享的人是我学习的榜样。 他们的行为也改变了我对教育的态度: 降低知识传递的门槛免费 奉献我的所学正是受这种态度的影响。 通过 【赞助莫烦】 能让我感到认同,我也更有理由坚持下去。

    数据的伙伴 Pandas