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

导航至

在这篇文章中,您将学习如何使用pandas的merge()操作合并不同的数据集或DataFrame。我们将深入探讨merge()函数的参数、它们的含义以及如何使用它们。我们还将了解merge()函数与pandas的concat()join()函数的区别。

Pandas中的合并是什么?

Python 的 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 连接。内部连接始终返回基于用作合并键的列的 DataFrame 中的匹配行。如果没有指定使用 how 参数执行合并的方式,则默认执行内部连接。

让我们看一个例子

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 — 在两者都存在的 ward 列上的合并。默认情况下,新 DataFrame 在 state 列后附加了 _x_y 后缀,因为源数据集中有类似命名的列。但是,您可以为新 DataFrame 定义任何重叠列的正确后缀。在执行内部连接时,会返回两个 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

左连接的结果显示,返回了左侧DataFrame alderman_df 的所有行。然而,对于没有匹配列键的 population_df,缺失值用 NaN 表示。

右连接

在两个DataFrame上执行右连接与左连接一样简单。只需将 how 参数的值指定为 right。返回右侧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

外连接

除了内连接、左连接和右连接之外,还有外连接。外连接返回两个数据集的所有行,无论键列是否有匹配。本质上,外连接将返回合并数据集的所有行,不匹配的行用 NaN 来表示缺失值。我们将使用 alderman_dfpopulation_df 数据帧来查看外连接的结果。

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

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

如何在索引上合并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 列作为左右索引。返回了两个数据集的所有行,并且在左右索引上不考虑匹配值。因此,新数据集中有五行。

合并和连接的区别

concat和merge有什么区别?pandas的 concat() 函数用于垂直或水平合并DataFrame或命名Series。默认情况下,concat() 函数垂直连接DataFrame。或者,将 axis 参数的值设置为 1 将得到水平合并。与 merge() 函数不同,在连接时,DataFrame只能执行外连接或内连接。

以下是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()concat()函数外,pandas还提供了DataFrame的join()方法,用于将不同的数据集合并成一个新的数据集。在参数和操作方面,join()方法与merge()函数相似。但两者最大的区别是,join方法基于索引合并DataFrame,而merge方法则同时基于索引和列合并。默认情况下,join()方法执行的是左连接,而merge方法执行的是内连接

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

请注意,这里执行的是内连接,因为返回了alderman_df的所有行,而在索引与右DataFrame population_df不匹配的地方,缺失的数据用NaN表示。

总结

总的来说,pandas的merge()操作是合并数据集最灵活的方法。它允许您根据索引或列合并DataFrame。该函数还执行不同类型的连接:内连接、外连接、左连接、右连接和笛卡尔连接。它通常是pandas中合并数据集最常用的方法或函数。在pandas中,merge的替代方法是什么?通常,concat()join()方法是pandas中merge的替代方法。

concat()函数在垂直堆叠一系列DataFrame时非常理想。此外,它还用于水平连接数据表,并且限于内连接到外连接。

join()方法简单直观,当需要按索引合并数据集时经常使用。默认情况下,它执行左连接,以及外连接内连接右连接

根据您的需求,您可以在分析之前选择这些方法中的任何一种来合并您的数据集。

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