Pandas 合并操作:它是什么以及何时使用它

导航至

在本文中,您将学习如何使用 pandas merge() 操作合并不同的数据集或 DataFrame。我们将仔细研究 merge() 函数的参数、它们的含义以及如何使用它们。我们还将了解 merge() 函数与 pandas concat()join() 函数的不同之处。

什么是 Pandas 中的合并?

pandas 库有一个名为 merge() 的方法,用于将 DataFrame 或命名的 Series 组合成一个单一的 DataFrame,以便更好地进行数据分析。pandas 合并操作基于列或索引组合两个或多个 DataFrame 对象,其方式类似于在数据库上执行的连接操作。目标是拥有一个新的数据集,同时源数据保持不变。

可以使用 pandas merge() 函数或 DataFrame merge() 方法执行 pandas 合并。

以下是 pandas merge() 函数的语法

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

pd.merge() 函数参数解释如下

  • left:这表示要合并的左侧 DataFrame 或命名的 Series。
  • right:这表示要合并的右侧 DataFrame 或命名的 Series。
  • how:这定义了要执行的合并类型。默认值为 inner;其他包括 outercrossleftright
  • on:这指定要连接的列或索引。两个 DataFrame 都必须具有相同的列才能进行连接;否则,将使用两个列的交集。
  • left_on:这在左侧 DataFrame 中指定要连接的列或索引。
  • right_on:这在右侧 DataFrame 中指定要连接的列或索引。
  • left_index:这使用左侧 DataFrame 的索引进行合并。
  • right_index:这使用右侧 DataFrame 的索引进行合并。
  • suffixes:这概述了要在左侧和右侧 DataFrame 中重叠的列名上使用的后缀。

让我们看看如何在两个 DataFrame 上执行 pandas 合并。

内连接

使用 merge() 函数合并 DataFrame 的一种方法是使用 inner 连接。inner 连接始终从 DataFrame 返回基于用作合并键的列的匹配行。当您不使用 how 参数指定应如何完成合并时,默认情况下会执行 inner 连接。

让我们看一个例子

import pandas as pd

alderman_data = {
    'ward': [1, 3, 4, 5, 6],
    'alderman': ['Vicky Mintoff', 'Petrina Finney', 'Kennith Gossop', 'Northrup Jaquet', 'Kelby Thaxton'],
    'address': ['7 Eggendart Pass', '2 Aberg Circle', '9 Barnett Way', '3 Anhalt Street', '86 Drewry Drive'],
    'phone': ['773-450-9926', '312-915-4064', '312-144-7339', '309-237-8875', '309-486-6591'],
    'state': ['Illinois', 'Illinois', 'Illinois', 'Illinois', 'Illinois']
}

alderman_df = pd.DataFrame(alderman_data)

population_data = {
    'ward': [1, 2, 3, 5, 7],
    'pop_2015': [25112, 27557, 27043, 26360, 27467],
    'pop_2020': [36778, 43417, 54184, 37978, 55985],
    'pop_change': [11666, 15860, 27141, 11618, 28518],
    'city': ['Chicago', 'Peoria', 'Chicago', 'Chicago', 'Springfield'],
    'state': ['Illinois', 'Illinois', 'Illinois', 'Illinois', 'Illinois'],
    'zip': [60691, 61635, 60604, 60614, 62794]
}

population_df = pd.DataFrame(population_data)

print(alderman_df)
print()
print(population_df)

以下是上述代码的输出

Alderman DataFrame:
ward	alderman	address	phone	state
0	1	Vicky Mintoff	7 Eggendart Pass	773-450-9926	Illinois
1	3	Petrina Finney	2 Aberg Circle	312-915-4064	Illinois
2	4	Kennith Gossop	9 Barnett Way	312-144-7339	Illinois
3	5	Northrup Jaquet	3 Anhalt Street	309-237-8875	Illinois
4	6	Kelby Thaxton	86 Drewry Drive	309-486-6591	Illinois

Ward Population DataFrame:
	ward	pop_2015	pop_2020	pop_change	city	state	zip
0	1	25112	36778	11666	Chicago	Illinois	60691
1	2	27557	43417	15860	Peoria	Illinois	61635
2	3	27043	54184	27141	Chicago	Illinois	60604
3	5	26360	37978	11618	Chicago	Illinois	60614
4	7	27467	55985	28518	Springfield	Illinois	62794;

让我们合并 alderman_dfpopulation_df,看看结果。

merged_df = pd.merge(alderman_df, population_df, on="ward")
print(merged_df.head())

以下是上述代码的输出

ward         alderman           address         phone   state_x  pop_2015   
0     1    Vicky Mintoff  7 Eggendart Pass  773-450-9926  Illinois     25112  \
1     3   Petrina Finney    2 Aberg Circle  312-915-4064  Illinois     27043   
2     5  Northrup Jaquet   3 Anhalt Street  309-237-8875  Illinois     26360   

   pop_2020  pop_change     city   state_y    zip  
0     36778       11666  Chicago  Illinois  60691  
1     54184       27141  Chicago  Illinois  60604  
2     37978       11618  Chicago  Illinois  60614

从上面的代码可以看出,我们对两个 DataFrame(alderman_dfpopulation_df)执行了合并,合并的列是两个 DataFrame 中都存在的 ward 列。默认情况下,新的 DataFrame 在 state 列后附加了 _x_y 后缀,因为它们在源数据集中具有相似命名的列。但是,您可以为新 DataFrame 中的任何重叠列定义适当的后缀。执行 inner 连接时,将返回两个 DataFrame 中都具有匹配值的行。在本例中,返回了行 135,因为要合并的原始 DataFrame 中的 ward 列具有匹配的值。

左连接

合并 DataFrame 或命名 Series 的另一种方法是使用 how 参数指定 left 连接。左连接返回左侧 DataFrame 中的所有行以及右侧 DataFrame 中键列匹配的行。

在此示例中,我们将仍然使用 alderman_dfpopulation_df

left_merge_df = pd.merge(alderman_df, population_df, on='ward', how='left')
print(left_merged_df)

以下是上述代码的输出

ward         alderman           address         phone   state_x  pop_2015   
0     1    Vicky Mintoff  7 Eggendart Pass  773-450-9926  Illinois   25112.0  \
1     3   Petrina Finney    2 Aberg Circle  312-915-4064  Illinois   27043.0   
2     4   Kennith Gossop     9 Barnett Way  312-144-7339  Illinois       NaN   
3     5  Northrup Jaquet   3 Anhalt Street  309-237-8875  Illinois   26360.0   
4     6    Kelby Thaxton   86 Drewry Drive  309-486-6591  Illinois       NaN   

   pop_2020  pop_change     city   state_y      zip  
0   36778.0     11666.0  Chicago  Illinois  60691.0  
1   54184.0     27141.0  Chicago  Illinois  60604.0  
2       NaN         NaN      NaN       NaN      NaN  
3   37978.0     11618.0  Chicago  Illinois  60614.0  
4       NaN         NaN      NaN       NaN      NaN

left 连接的结果表明,返回了左侧 DataFrame alderman_df 中的所有数据行。但是,对于没有匹配列键的 population_df,缺失值用 NaN 表示。

右连接

对两个 DataFrame 执行 right 连接就像我们对 left 连接所做的那样容易。只需将 right 指定为 how 参数的值即可。将返回右侧 DataFrame 中的所有行,并且还将返回左侧 DataFrame 中与键列匹配的行。

right_merge_df = pd.merge(alderman_df, population_df, on='ward', how='right')
print(right_merge_df)

以下是上述代码的输出

  ward         alderman           address         phone   state_x  pop_2015   
0     1    Vicky Mintoff  7 Eggendart Pass  773-450-9926  Illinois     25112  \
1     2              NaN               NaN           NaN       NaN     27557   
2     3   Petrina Finney    2 Aberg Circle  312-915-4064  Illinois     27043   
3     5  Northrup Jaquet   3 Anhalt Street  309-237-8875  Illinois     26360   
4     7              NaN               NaN           NaN       NaN     27467   

   pop_2020  pop_change         city   state_y    zip  
0     36778       11666      Chicago  Illinois  60691  
1     43417       15860       Peoria  Illinois  61635  
2     54184       27141      Chicago  Illinois  60604  
3     37978       11618      Chicago  Illinois  60614  
4     55985       28518  Springfield  Illinois  62794

外连接

除了 innerleftright 连接之外,还有 outer 连接。outer 连接返回来自两个数据集的所有行,无论键列中是否存在匹配项。本质上,outer 连接将返回来自合并数据集的所有行,不匹配的行将使用 NaN 来指示缺失值。我们将使用 alderman_dfpopulation_df DataFrame 查看外连接的结果。

outer_merge_df = pd.merge(alderman_df, population_df, on='ward', how='outer')

print(outer_merge_df)

以下是上述代码的输出

 ward         alderman           address         phone   state_x  pop_2015   
0     1    Vicky Mintoff  7 Eggendart Pass  773-450-9926  Illinois   25112.0  \
1     3   Petrina Finney    2 Aberg Circle  312-915-4064  Illinois   27043.0   
2     4   Kennith Gossop     9 Barnett Way  312-144-7339  Illinois       NaN   
3     5  Northrup Jaquet   3 Anhalt Street  309-237-8875  Illinois   26360.0   
4     6    Kelby Thaxton   86 Drewry Drive  309-486-6591  Illinois       NaN   
5     2              NaN               NaN           NaN       NaN   27557.0   
6     7              NaN               NaN           NaN       NaN   27467.0   

   pop_2020  pop_change         city   state_y      zip  
0   36778.0     11666.0      Chicago  Illinois  60691.0  
1   54184.0     27141.0      Chicago  Illinois  60604.0  
2       NaN         NaN          NaN       NaN      NaN  
3   37978.0     11618.0      Chicago  Illinois  60614.0  
4       NaN         NaN          NaN       NaN      NaN  
5   43417.0     15860.0       Peoria  Illinois  61635.0  
6   55985.0     28518.0  Springfield  Illinois  62794.0

从上面的代码片段中,outer 连接返回了七行数据,以容纳来自 alderman_dfpopulation_df 的所有行。在 outer 连接中合并的两个数据集各自有五行数据。

如何在索引上合并 DataFrame

可以通过为 left_onright_onleft_indexright_index 参数提供参数,基于数据集的索引合并数据集。使用任何其他上述参数时,需要遵守一些规则

  • 您只能传递参数 left_onleft_index,不能同时传递两者。
  • 您只能传递参数 right_onright_index,不能同时传递两者。
  • 您只能传递参数 onleft_onright_on,不能同时传递两者的组合。
  • 您只能传递参数 onleft_indexright_index,不能同时传递两者的组合。

使用 left_onright_on 参数,您传递参数以指示分别用于在左侧和右侧合并的列。对于 left_indexright_index 参数,您将两个参数都设置为 True

让我们看一个例子

index_merge_df = pd.merge(alderman_df, population_df, left_index=True, right_index=True)

print(index_merge_df)

以下是上述代码的输出

 ward_x         alderman           address         phone   state_x  ward_y   
0       1    Vicky Mintoff  7 Eggendart Pass  773-450-9926  Illinois       1  \
1       3   Petrina Finney    2 Aberg Circle  312-915-4064  Illinois       2   
2       4   Kennith Gossop     9 Barnett Way  312-144-7339  Illinois       3   
3       5  Northrup Jaquet   3 Anhalt Street  309-237-8875  Illinois       5   
4       6    Kelby Thaxton   86 Drewry Drive  309-486-6591  Illinois       7   

   pop_2015  pop_2020  pop_change         city   state_y    zip  
0     25112     36778       11666      Chicago  Illinois  60691  
1     27557     43417       15860       Peoria  Illinois  61635  
2     27043     54184       27141      Chicago  Illinois  60604  
3     26360     37978       11618      Chicago  Illinois  60614  
4     27467     55985       28518  Springfield  Illinois  62794

从我们代码的输出中,merge 函数使用每个数据集的 ward 列作为左侧和右侧索引。返回了来自两个数据集的所有行,并且在左侧或右侧索引上未考虑匹配值。因此,我们在新数据集中有五行。

Merge 和 Concat 之间的区别

Concat 和 Merge 之间有什么区别?pandas concat() 函数用于垂直或水平组合 DataFrame 或命名 Series。默认情况下,concat() 函数垂直连接 DataFrame。或者,将 axis 参数参数设置为 1 会给出水平合并。与 merge() 函数不同,在连接时,只能对 DataFrame 执行 outerinner 连接。

以下是 pandas concat() 函数的语法

pandas.concat(objs, *, axis=0, join='outer', ignore_index=False, keys=None, levels=None, names=None, verify_integrity=False, sort=False, copy=None)

让我们看一个例子

alderman_data2 = {
    'ward': [9, 10, 11, 12, 13],
    'alderman': ['Vicky Griffin', 'Blake Finney', 'Greg Theodore', 'Jacqueline Bob', 'Shelby Boston'],
    'address': ['7 Haas Circle', '2 Mayer Lane', '9 Harper Drive', '3 Grover Avenue', '86 Palm Drive'],
    'phone': ['312-978-5864', '217-352-4548', '312-568-4492', '815-254-3682', '309-590-9629'],
    'state': ['Illinois', 'Illinois', 'Illinois', 'Illinois', 'Illinois']
}

alderman_df2 = pd.DataFrame(alderman_data2)

concat_df = pd.concat([alderman_df, alderman_df2])

print(concat_df)

以下是上述代码的输出

 ward         alderman           address         phone     state
0     1    Vicky Mintoff  7 Eggendart Pass  773-450-9926  Illinois
1     3   Petrina Finney    2 Aberg Circle  312-915-4064  Illinois
2     4   Kennith Gossop     9 Barnett Way  312-144-7339  Illinois
3     5  Northrup Jaquet   3 Anhalt Street  309-237-8875  Illinois
4     6    Kelby Thaxton   86 Drewry Drive  309-486-6591  Illinois
0     9    Vicky Griffin     7 Haas Circle  312-978-5864  Illinois
1    10     Blake Finney      2 Mayer Lane  217-352-4548  Illinois
2    11    Greg Theodore    9 Harper Drive  312-568-4492  Illinois
3    12   Jacqueline Bob   3 Grover Avenue  815-254-3682  Illinois
4    13    Shelby Boston     86 Palm Drive  309-590-9629  Illinois

使用 concat() 函数垂直组合了两个 DataFrame 对象 alderman_dfalderman_df2。组合的两个数据集仍然保留其原始索引;但是,可以通过将 ignore_index 参数参数设置为 True 来覆盖此行为。

pandas concat() 函数的常见用例是垂直堆叠在不同时间点获得的相似数据。在上面的示例中,将 Alderman 列表的第二部分添加到前一部分以延长列表。它也可以用于为数据提供分层索引。

Pandas Merge 和 Join 方法之间的区别

除了 merge()concat() 函数之外,pandas 还提供了 DataFrame join() 方法,用于将不同的数据集组合成一个新的数据集。就参数和操作而言,join() 方法类似于 merge() 函数。但是,两者之间最大的区别在于 join 基于索引组合 DataFrame,而 merge 同时基于索引或列进行组合。默认情况下,join() 方法执行 left 连接,而 merge 执行 inner 连接。

join() 方法语法如下所示

DataFrame.join(other, on=None, how='left', lsuffix='', rsuffix='', sort=False, validate=None)

这是一个例子

joined_df = alderman_df.join(population_df, on='ward', lsuffix='_x', rsuffix='_y')

print(joined_df)

以下是上述代码的输出

ward_x         alderman           address         phone   state_x  ward_y   
0       1    Vicky Mintoff  7 Eggendart Pass  773-450-9926  Illinois     2.0  \
1       3   Petrina Finney    2 Aberg Circle  312-915-4064  Illinois     5.0   
2       4   Kennith Gossop     9 Barnett Way  312-144-7339  Illinois     7.0   
3       5  Northrup Jaquet   3 Anhalt Street  309-237-8875  Illinois     NaN   
4       6    Kelby Thaxton   86 Drewry Drive  309-486-6591  Illinois     NaN   

   pop_2015  pop_2020  pop_change         city   state_y      zip  
0   27557.0   43417.0     15860.0       Peoria  Illinois  61635.0  
1   26360.0   37978.0     11618.0      Chicago  Illinois  60614.0  
2   27467.0   55985.0     28518.0  Springfield  Illinois  62794.0  
3       NaN       NaN         NaN          NaN       NaN      NaN  
4       NaN       NaN         NaN          NaN       NaN      NaN

请注意,执行了 inner 连接,因为返回了 alderman_df 中的所有数据行,而缺失数据的行用 NaN 表示,其中索引与右侧 DataFrame population_df 不匹配。

总结

总而言之,pandas merge() 操作是组合数据集的最灵活方法。它使您可以选择基于索引或列连接 DataFrame。该函数还执行不同类型的连接:inner、outer、left、right 和 cross。它通常是 pandas 中用于组合数据集的最常用方法或函数。pandas 中 merge 的替代方法是什么?一般来说,concat()join() 方法是 pandas merge 的替代方法。

当垂直堆叠一系列 DataFrame 时,concat() 函数是理想的选择。此外,它用于水平连接数据表,并且仅限于 inner 到 outer 连接。

当您需要沿着索引组合数据集时,join() 方法简单明了且经常使用。默认情况下,它执行 left 连接以及 outerinnerright 连接。

根据您的需要,您可以选择这些方法中的任何一种来组合数据集,然后再进行分析。

这篇文章由 Iniubong Arthur 撰写。Iniubong 是一位软件开发人员和技术作家,拥有 2 年以上的行业经验。他编写 Python、Java、JavaScript,并且还使用 Django 和 React 构建项目。