6.1 数据合并 (merge)


文档摘要

6.1 数据合并 (merge) Pandas 数据合并 (merge) 详解 函数的基本用法 函数的基本语法如下: 其中一些重要的参数解释如下: : 左侧 DataFrame。 : 右侧 DataFrame。 : 连接方式,可选值包括 , , , ,默认为 。 : 用于连接的列名,必须同时存在于左右两个 DataFrame 中。 : 左侧 DataFrame 用于连接的列名。 : 右侧 DataFrame 用于连接的列名。 : 如果为 ,则使用左侧 DataFrame 的索引作为连接键。 : 如果为 ,则使用右侧 DataFrame 的索引作为连接键。 : 如果左右 DataFrame 中存在相同的列名,则在结果中添加后缀以区分,默认为 。

6.1 数据合并 (merge)

Pandas 数据合并 (merge) 详解

1. merge 函数的基本用法

merge 函数的基本语法如下:

pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None, left_index=False, right_index=False, sort=False, suffixes=('_x', '_y'), copy=True, indicator=False, validate=None)

其中一些重要的参数解释如下:

  • left: 左侧 DataFrame。

  • right: 右侧 DataFrame。

  • how: 连接方式,可选值包括 'inner', 'outer', 'left', 'right',默认为 'inner'

  • on: 用于连接的列名,必须同时存在于左右两个 DataFrame 中。

  • left_on: 左侧 DataFrame 用于连接的列名。

  • right_on: 右侧 DataFrame 用于连接的列名。

  • left_index: 如果为 True,则使用左侧 DataFrame 的索引作为连接键。

  • right_index: 如果为 True,则使用右侧 DataFrame 的索引作为连接键。

  • suffixes: 如果左右 DataFrame 中存在相同的列名,则在结果中添加后缀以区分,默认为 ('_x', '_y')

  • indicator: 如果为 True,则在结果中添加 _merge 列,用于指示每一行数据的来源。

2. 连接方式 (how)

how 参数决定了连接的方式,Pandas 提供了四种主要的连接方式:

  • inner: 内连接,只保留两个 DataFrame 中都存在的键对应的数据。

  • outer: 外连接,保留两个 DataFrame 中所有键对应的数据,缺失值用 NaN 填充。

  • left: 左连接,保留左侧 DataFrame 中所有键对应的数据,右侧 DataFrame 中不存在的键用 NaN 填充。

  • right: 右连接,保留右侧 DataFrame 中所有键对应的数据,左侧 DataFrame 中不存在的键用 NaN 填充。

下面通过代码示例来说明不同连接方式的效果:

import pandas as pd # 创建两个 DataFrame df1 = pd.DataFrame({'key': ['A', 'B', 'C', 'D'], 'value1': [1, 2, 3, 4]}) df2 = pd.DataFrame({'key': ['B', 'D', 'E', 'F'], 'value2': [5, 6, 7, 8]}) print("DataFrame 1:\n", df1) print("\nDataFrame 2:\n", df2) # 内连接 inner_merged = pd.merge(df1, df2, on='key', how='inner') print("\nInner Merge:\n", inner_merged) # 外连接 outer_merged = pd.merge(df1, df2, on='key', how='outer') print("\nOuter Merge:\n", outer_merged) # 左连接 left_merged = pd.merge(df1, df2, on='key', how='left') print("\nLeft Merge:\n", left_merged) # 右连接 right_merged = pd.merge(df1, df2, on='key', how='right') print("\nRight Merge:\n", right_merged)

输出结果如下:

DataFrame 1: key value1 0 A 1 1 B 2 2 C 3 3 D 4 DataFrame 2: key value2 0 B 5 1 D 6 2 E 7 3 F 8 Inner Merge: key value1 value2 0 B 2 5 1 D 4 6 Outer Merge: key value1 value2 0 A 1.0 NaN 1 B 2.0 5.0 2 C 3.0 NaN 3 D 4.0 6.0 4 E NaN 7.0 5 F NaN 8.0 Left Merge: key value1 value2 0 A 1 NaN 1 B 2 5.0 2 C 3 NaN 3 D 4 6.0 Right Merge: key value1 value2 0 B 2.0 5 1 D 4.0 6 2 E NaN 7 3 F NaN 8

可以使用 mermaid 图示来更直观地展示不同连接方式的结果:

3. 使用不同的列名进行连接

如果两个 DataFrame 中用于连接的列名不同,可以使用 left_onright_on 参数来指定:

df1 = pd.DataFrame({'id': ['A', 'B', 'C', 'D'], 'value1': [1, 2, 3, 4]}) df2 = pd.DataFrame({'ID': ['B', 'D', 'E', 'F'], 'value2': [5, 6, 7, 8]}) merged = pd.merge(df1, df2, left_on='id', right_on='ID', how='inner') print(merged)

输出结果:

id value1 ID value2 0 B 2 B 5 1 D 4 D 6

注意,使用 left_onright_on 连接后,结果中会同时包含用于连接的两个列,如果不需要,可以使用 drop 方法删除其中一列。

4. 使用索引进行连接

如果需要使用 DataFrame 的索引作为连接键,可以将 left_indexright_index 参数设置为 True

df1 = pd.DataFrame({'value1': [1, 2, 3, 4]}, index=['A', 'B', 'C', 'D']) df2 = pd.DataFrame({'value2': [5, 6, 7, 8]}, index=['B', 'D', 'E', 'F']) merged = pd.merge(df1, df2, left_index=True, right_index=True, how='inner') print(merged)

输出结果:

value1 value2 B 2 5 D 4 6

5. 处理重复键

当两个 DataFrame 中都存在重复的键时,merge 函数会将所有可能的组合都连接起来,这可能会导致结果 DataFrame 的行数显著增加。

df1 = pd.DataFrame({'key': ['A', 'A', 'B', 'C'], 'value1': [1, 2, 3, 4]}) df2 = pd.DataFrame({'key': ['A', 'B', 'B', 'D'], 'value2': [5, 6, 7, 8]}) merged = pd.merge(df1, df2, on='key', how='inner') print(merged)

输出结果:

key value1 value2 0 A 1 5 1 A 2 5 2 B 3 6 3 B 3 7

可以看到,由于 key'A''B' 的行在两个 DataFrame 中都存在多个,因此结果中出现了多行。 理解这一点非常重要,特别是在处理大型数据集时,重复键可能会导致内存溢出或性能问题。

6. 处理列名冲突

当两个 DataFrame 中存在相同的列名,但又不是连接键时,merge 函数会自动在结果中添加后缀以区分,默认的后缀是 _x_y。 可以使用 suffixes 参数自定义后缀:

df1 = pd.DataFrame({'key': ['A', 'B', 'C', 'D'], 'value': [1, 2, 3, 4]}) df2 = pd.DataFrame({'key': ['B', 'D', 'E', 'F'], 'value': [5, 6, 7, 8]}) merged = pd.merge(df1, df2, on='key', how='inner', suffixes=('_left', '_right')) print(merged)

输出结果:

key value_left value_right 0 B 2 5 1 D 4 6

7. indicator 参数

indicator 参数可以添加一个名为 _merge 的列,用于指示每一行数据的来源。该列的值可以是 'left_only''right_only''both'

df1 = pd.DataFrame({'key': ['A', 'B', 'C', 'D'], 'value1': [1, 2, 3, 4]}) df2 = pd.DataFrame({'key': ['B', 'D', 'E', 'F'], 'value2': [5, 6, 7, 8]}) merged = pd.merge(df1, df2, on='key', how='outer', indicator=True) print(merged)

输出结果:

key value1 value2 _merge 0 A 1.0 NaN left_only 1 B 2.0 5.0 both 2 C 3.0 NaN left_only 3 D 4.0 6.0 both 4 E NaN 7.0 right_only 5 F NaN 8.0 right_only

8. validate 参数

validate 参数可以用于检查连接的类型,以确保数据的一致性。可选值包括:

  • 'one_to_one''1:1':检查连接键在两个 DataFrame 中都是唯一的。

  • 'one_to_many''1:m':检查连接键在左侧 DataFrame 中是唯一的。

  • 'many_to_one''m:1':检查连接键在右侧 DataFrame 中是唯一的。

  • 'many_to_many''m:m':允许连接键在两个 DataFrame 中都存在重复。

如果连接类型与 validate 参数不符,则会引发 MergeError 异常。

df1 = pd.DataFrame({'key': ['A', 'B', 'C', 'D'], 'value1': [1, 2, 3, 4]}) df2 = pd.DataFrame({'key': ['B', 'D', 'E', 'F'], 'value2': [5, 6, 7, 8]}) try: merged = pd.merge(df1, df2, on='key', how='inner', validate='one_to_one') print(merged) except pd.errors.MergeError as e: print(f"MergeError: {e}")

由于本例中连接键在两个DataFrame中都是唯一的,因此不会引发错误。 但是如果 df1 有重复的 key 值,就会引发错误。

9. 性能优化

对于大型数据集,merge 操作可能会比较耗时。以下是一些可以提高性能的建议:

  • 确保连接键的数据类型一致: 如果连接键的数据类型不一致,Pandas 会自动进行类型转换,这会降低性能。

  • 提前排序: 如果 DataFrame 已经按照连接键排序,可以设置 sort=False,避免 Pandas 重新排序。

  • 使用 Categorical 类型: 如果连接键是字符串类型,可以将其转换为 Categorical 类型,以减少内存占用和提高比较速度。

总结

merge 函数是 Pandas 中一个非常强大的数据合并工具,可以灵活地根据不同的需求进行数据连接。 通过理解其各种参数和连接方式,可以高效地整合来自不同数据源的数据,为后续的数据分析和建模奠定基础。 在实际应用中,需要根据数据的特点选择合适的连接方式,并注意处理重复键和列名冲突等问题,以确保结果的正确性和可靠性。 此外,对于大型数据集,还需要注意性能优化,以提高数据处理的效率。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U