数据分析必备:DataFrame 联合与合并数据集

243 阅读4分钟

1、合并 merge

在 Pandas 中,merge 函数可以用于合并两个 DataFrame,类似于 SQL 中的 JOIN 操作。通过 merge ,我们可以根据一个或多个键将两个 DataFrame 结合在一起。以下图示为 merge 的相关函数参数,本文将介绍 merge 的常见参数,并演示相关例子。

我们看一个简单的例子,我们有两个 DataFrame,分别包含学生的基本信息和成绩信息,如下所示

import pandas as pd

students = pd.DataFrame({
    'id': [1, 2, 3],
    'name': ['小明', '小红', '小刚']
})

scores = pd.DataFrame({
    'id': [1, 2, 4],
    'score': [90, 85, 88]
})

students
# ---- 输出 ----
#   id  name
# 0	1	小明
# 1	2	小红
# 2	3	小刚

scores
# ---- 输出 ----
#   id  score
# 0	1	90
# 1	2	85
# 2	4	88

我们使用 merge 来关联以上两个 DataFrame 数据,如下所示

pd.merge(students, scores)
# ---- 输出 ----
#   id	name   score
# 0	1	小明	90
# 1	2	小红	85

以上是一个最简单的例子,我们并没有指定在哪一列上进行连接,但是也能实现两份数据关联。那是因为如果连接的键信息没有指定,merge 会自动将重叠列名作为连接的键。但是,在实际编码过程中显式地指定连接键才是好的实现:

pd.merge(students, scores, on='id')
# ---- 输出 ----
#   id	name   score
# 0	1	小明	90
# 1	2	小红	85

以上的两份 DataFrame 对象有相同的 key,但是如果两份 DataFrame 对象的 key 名字不一样的话,我们可以分别为它们指定列名

import pandas as pd

students = pd.DataFrame({
    'tid': [1, 2, 3],
    'name': ['小明', '小红', '小刚']
})

scores = pd.DataFrame({
    'cid': [1, 2, 4],
    'score': [90, 85, 88]
})

pd.merge(students, scores, left_on='tid', right_on='cid')
# ---- 输出 ----
# 	tid	name   cid score
# 0	1	小明	1	90
# 1	2	小红	2	85

默认情况下,merge 做的是内连接('inner'join),结果中的键是两张表的交集。其他可选的选项有’left'、'right’和’outer'。外连接(outer join)是键的并集,联合了左连接和右连接的效果:

pd.merge(students, scores, how='outer')

# ---- 输出 ----
#   id	name    score
# 0	1	小明	90.0
# 1	2	小红	85.0
# 2	3	小刚	NaN
# 3	4	NaN	    88.0

有时候,DataFrame 中用于合并的键是它的索引。在这种情况下,你可以传递 left_index=True 或right_index=True(或者都传)来表示索引需要用来作为合并的键:

import pandas as pd

students = pd.DataFrame({
    'name': ['小明', '小红', '小刚']
}, index = [1, 2, 3])

scores = pd.DataFrame({
    'score': [90, 85, 88]
}, index = [1, 2, 4])

pd.merge(students, scores, left_index=True, right_index=True)

# ---- 输出 ----
#   name   score
# 1	小明	90
# 2	小红	85

2、连接 join

DataFrame 有一个方便的 join 实例方法,用于按照索引合并。该方法也可以用于合并多个索引相同或相似但没有重叠列的 DataFrame 对象。在之前的例子中,我们可以这样写:

import pandas as pd

students = pd.DataFrame({
    'name': ['小明', '小红', '小刚']
}, index = [1, 2, 3])

scores = pd.DataFrame({
    'score': [90, 85, 88]
}, index = [1, 2, 4])

students.join(scores)

# ---- 输出 ----
#   name    score
# 1	小明	90.0
# 2	小红	85.0
# 3	小刚	NaN

由以上输出得知,join 默认采用的 left 合并方式,当然我们可以通过 how

students.join(scores, how='inner')

# ---- 输出 ----
# 	name	score
# 1	小明	90
# 2	小红	85

当然我们也可以通过 on 参数,将列索引和行索引进行关联,如下所示

import pandas as pd

students = pd.DataFrame({
    'id': [1, 2, 3],
    'name': ['小明', '小红', '小刚']
})

scores = pd.DataFrame({
    'score': [90, 85, 88]
}, index = [1, 2, 4])


students.join(scores, on='id')

# ---- 输出 ----
#   id	name   score
# 0	1	小明	90.0
# 1	2	小红	85.0
# 2	3	小刚	NaN

3、轴向连接 concat

concat 函数允许我们将多个 DataFrame 沿着行(axis=0)或列(axis=1)进行连接,它可以处理不同的索引和列名,并提供了一些选项来处理这些情况

我们可以按行来连接 DataFrame 对象,如下所示

import pandas as pd

df1 = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})
df2 = pd.DataFrame({'A': [5, 6], 'B': [7, 8]})

# 按行连接
result = pd.concat([df1, df2], axis=0)
result

# ---- 输出 ----
#   A	B
# 0	1	3
# 1	2	4
# 0	5	7
# 1	6	8

我们也可以通过列连接两个 DataFrame 对象,通过设置 axis=1,如下所示

df3 = pd.DataFrame({'C': [9, 10]})
df4 = pd.DataFrame({'D': [11, 12]})

result_col = pd.concat([df3, df4], axis=1)
result_col
# ---- 输出 ----
#   C	D
# 0	9	11
# 1	10	12

4、联合重叠数据 combine_first

combine_first 是 Pandas 中一个非常有用的方法,它用于合并两个 DataFrame,并优先保留第一个 DataFrame 中的非缺失值(NaN),如果第一个 DataFrame 中的值为 NaN,则使用第二个 DataFrame 中的值。

下面是一个简单的例子,展示如何使用 combine_first 方法。

import pandas as pd

# 创建两个 DataFrame
df1 = pd.DataFrame({
    'A': [1, 2, None],
    'B': [None, 5, 6]
}, index=['a', 'b', 'c'])

df2 = pd.DataFrame({
    'A': [None, 3, 4],
    'B': [7, None, None]
}, index=['a', 'b', 'c'])


print(df1)
# ---- 输出 ----
#      A    B
# a  1.0  NaN
# b  2.0  5.0
# c  NaN  6.0

print(df2)
# ---- 输出 ----
#     A    B
# a  NaN  7.0
# b  3.0  NaN
# c  4.0  NaN

# 使用 combine_first 方法合并两个 DataFrame
result = df1.combine_first(df2)
print(result)
#      A    B
# a  1.0  7.0
# b  2.0  5.0
# c  4.0  6.0

如果你喜欢本文,欢迎点赞,并且关注我们的微信公众号:Python技术极客,我们会持续更新分享 Python 开发编程、数据分析、数据挖掘、AI 人工智能、网络爬虫等技术文章!让大家在Python 技术领域持续精进提升,成为更好的自己!

添加作者微信(coder_0101),拉你进入行业技术交流群,进行技术交流~