Pandas Join

Pandas 中的 join 操作根据索引将两个 DataFrame 连接起来。

让我们看一个例子。

import pandas as pd

# create dataframe 1
data1 = {
    'A': ['A0', 'A1', 'A2', 'A3'],
    'B': ['B0', 'B1', 'B2', 'B3'],
}
df1 = pd.DataFrame(data1, index=['K0', 'K1', 'K2', 'K3'])

# create dataframe 2
data2 = {
    'C': ['C0', 'C1', 'C2', 'C3'],
    'D': ['D0', 'D1', 'D2', 'D3'],
}
df2 = pd.DataFrame(data2, index=['K0', 'K1', 'K2', 'K3'])

# join dataframes df_join = df1.join(df2)
# display DataFrames print("DataFrame 1:\n", df1) print("\nDataFrame 2:\n", df2) print("\nJoined DataFrame:\n", df_join)

输出

DataFrame 1:
     A   B
K0  A0  B0
K1  A1  B1
K2  A2  B2
K3  A3  B3

DataFrame 2:
     C   D
K0  C0  D0
K1  C1  D1
K2  C2  D2
K3  C3  D3

Joined DataFrame:
     A   B   C   D
K0  A0  B0  C0  D0
K1  A1  B1  C1  D1
K2  A2  B2  C2  D2
K3  A3  B3  C3  D3

在此示例中,我们使用 join() 连接了 DataFrame df1df2

在这里,我们在两个 DataFrame 中都指定了 index= ['K0', 'K1', 'K2', 'K3']。这是为了提供一个通用的索引列,我们可以在此基础上执行 join 操作。


join() 语法

Pandas 中 join() 方法的语法是

df1.join(df2, on=None, how='left', lsuffix='', rsuffix='', sort=False)

这里,

  • df1:第一个 DataFrame
  • df2:要连接到第一个 DataFrame 的 DataFrame
  • on(optional):指定用于连接 DataFrame 的索引列
  • how(optional):指定要执行的 join 类型
  • lsuffix(optional):指定一个后缀,如果与另一个列名发生冲突,则将附加到第一个 DataFrame 的列名
  • rsuffix(optional):指定一个后缀,如果与另一个列名发生冲突,则将附加到第二个 DataFrame 的列名
  • sort(optional):确定是否按 join 键对结果 DataFrame 进行排序

示例:连接 DataFrames

如上所述,join() 方法只能基于索引连接 DataFrame。但是,我们可以通过将列传递给 set_index() 来将其视为索引。然后,我们可以使用该列来连接 DataFrame。

让我们看一个例子。

import pandas as pd

# create dataframes from the dictionaries
data1 = {
    'EmployeeID' : ['E001', 'E002', 'E003', 'E004', 'E005'],
    'Name' : ['John Doe', 'Jane Smith', 'Peter Brown', 'Tom Johnson', 'Rita Patel'],
    'DeptID': ['D001', 'D003', 'D001', 'D002', 'D006'],
    'DeptName': ['Sales1', 'Admin1', 'Sales1', 'HR1', 'N/A']
}
employees = pd.DataFrame(data1)

data2 = {
    'DeptID' : ['D001', 'D002', 'D003', 'D004'],
    'DeptName' : ['Sales2', 'HR2', 'Admin2', 'Marketing2']
}
departments = pd.DataFrame(data2)

# set DeptID as index for departments dataframe departments = departments.set_index('DeptID') # join the dataframes based on columns df_join = employees.join(departments, on = 'DeptID', lsuffix = '_left', rsuffix = '_right')
print(df_join)

输出

  EmployeeID         Name DeptID DeptName_left DeptName_right
0       E001     John Doe   D001        Sales1         Sales2
1       E002   Jane Smith   D003        Admin1         Admin2
2       E003  Peter Brown   D001        Sales1         Sales2
3       E004  Tom Johnson   D002           HR1            HR2
4       E005   Rita Patel   D006           N/A            NaN

在上面的示例中,我们使用 join() 方法对两个 DataFrame employeesdepartments 执行了 join 操作。

注意这行:

departments = departments.set_index('DeptID')

在这里,我们将 DeptID 列设置为索引。

另外,请注意,我们已将 DeptID 设置为 departments 的索引,但未将其设置为 employees 的索引。这是因为用于 join 的列应该是右侧 DataFrame 的索引,而不是总是左侧 DataFrame 的索引。

在这种情况下,我们需要使用 on 参数。

df_join = employees.join(departments, on = 'DeptID', lsuffix = '_left', rsuffix = '_right')

在这一行中,我们使用了带有 lsuffixrsuffixon 参数。

两个 DataFrame 都有一个 DeptID 列。为了区分它们,我们在 DeptID 列上分别为 employees 添加了 _left,为 departments 添加了 _right


Join 类型

到目前为止,我们还没有定义 如何 join DataFrames,因此它默认为左连接。

但是,我们可以在 how 参数中指定 join 类型。以下是我们可以在 join() 方法中使用的 5 种 join 类型

  • 左连接(默认)
  • 右连接
  • 外连接
  • 内连接
  • 笛卡尔积连接

左连接

左连接根据公共键组合两个 DataFrame,并返回一个包含左侧 DataFrame 的所有行和右侧 DataFrame 的匹配行的新 DataFrame。

如果在右侧 DataFrame 中找不到值,则用 NaN 填充该空格。例如,

import pandas as pd

# create dataframes from the dictionaries
data1 = {
    'EmployeeID' : ['E001', 'E002', 'E003', 'E004', 'E005'],
    'Name' : ['John Doe', 'Jane Smith', 'Peter Brown', 'Tom Johnson', 'Rita Patel'],
    'DeptID': ['D001', 'D003', 'D001', 'D002', 'D005'],
}
employees = pd.DataFrame(data1)

data2 = {
    'DeptID': ['D001', 'D002', 'D003','D004'],
    'DeptName': ['Sales', 'HR', 'Admin', 'Marketing']
}
departments = pd.DataFrame(data2)

# set DeptID as index for departments
departments.set_index('DeptID',inplace=True)

# left join df_join = employees.join(departments, on = 'DeptID', how = 'left')
print(df_join)

输出

  EmployeeID         Name DeptID DeptName
0       E001     John Doe   D001    Sales
1       E002   Jane Smith   D003    Admin
2       E003  Peter Brown   D001    Sales
3       E004  Tom Johnson   D002       HR
4       E005   Rita Patel   D005      NaN

右连接

右连接是左连接的反向操作。它返回一个包含右侧 DataFrame 的所有行和左侧 DataFrame 的匹配行的新 DataFrame。

如果在左侧 DataFrame 中找不到值,则用 NaN 填充该空格。例如,

import pandas as pd

# create dataframes from the dictionaries
data1 = {
    'EmployeeID' : ['E001', 'E002', 'E003', 'E004', 'E005'],
    'Name' : ['John Doe', 'Jane Smith', 'Peter Brown', 'Tom Johnson', 'Rita Patel'],
    'DeptID': ['D001', 'D003', 'D001', 'D002', 'D005'],
}
employees = pd.DataFrame(data1)

data2 = {
    'DeptID': ['D001', 'D002', 'D003','D004'],
    'DeptName': ['Sales', 'HR', 'Admin', 'Marketing']
}
departments = pd.DataFrame(data2)

# set DeptID as index for departments
departments.set_index('DeptID', inplace=True)

# right join df_join = employees.join(departments, on = 'DeptID', how = 'right')
# reset index df_join.reset_index(drop=True, inplace=True) print(df_join)

输出

  EmployeeID         Name DeptID   DeptName
0       E001     John Doe   D001      Sales
1       E003  Peter Brown   D001      Sales
2       E004  Tom Johnson   D002         HR
3       E002   Jane Smith   D003      Admin
4        NaN          NaN   D004  Marketing

内连接

内连接根据公共键组合两个 DataFrame,并返回一个只包含在两个原始 DataFrame 中都有匹配值的新 DataFrame。

例如,

import pandas as pd

# create dataframes from the dictionaries
data1 = {
    'EmployeeID' : ['E001', 'E002', 'E003', 'E004', 'E005'],
    'Name' : ['John Doe', 'Jane Smith', 'Peter Brown', 'Tom Johnson', 'Rita Patel'],
    'DeptID': ['D001', 'D003', 'D001', 'D002', 'D005'],
}
employees = pd.DataFrame(data1)

data2 = {
    'DeptID': ['D001', 'D002', 'D003','D004'],
    'DeptName': ['Sales', 'HR', 'Admin', 'Marketing']
}
departments = pd.DataFrame(data2)

# set DeptID as index for departments
departments.set_index('DeptID',inplace=True)

# inner join df_join = employees.join(departments, on = 'DeptID', how = 'inner')
# reset index df_join.reset_index(drop=True, inplace=True) print(df_join)

输出

  EmployeeID         Name DeptID DeptName
0       E001     John Doe   D001    Sales
1       E003  Peter Brown   D001    Sales
2       E002   Jane Smith   D003    Admin
3       E004  Tom Johnson   D002       HR

外连接

外连接根据公共键组合两个 DataFrame。与内连接不同,外连接返回一个包含两个原始 DataFrame 中所有行的新 DataFrame。

如果在 DataFrame 中找不到值,则用 NaN 填充该空格。例如,

import pandas as pd

# create dataframes from the dictionaries
data1 = {
    'EmployeeID' : ['E001', 'E002', 'E003', 'E004', 'E005'],
    'Name' : ['John Doe', 'Jane Smith', 'Peter Brown', 'Tom Johnson', 'Rita Patel'],
    'DeptID': ['D001', 'D003', 'D001', 'D002', 'D005'],
}
employees = pd.DataFrame(data1)

data2 = {
    'DeptID': ['D001', 'D002', 'D003','D004'],
    'DeptName': ['Sales', 'HR', 'Admin', 'Marketing']
}
departments = pd.DataFrame(data2)

# set DeptID as index for departments
departments.set_index('DeptID',inplace=True)

# outer join df_join = employees.join(departments, on = 'DeptID', how = 'outer')
# reset index df_join.reset_index(drop=True, inplace=True) print(df_join)

输出

  EmployeeID         Name DeptID   DeptName
0       E001     John Doe   D001      Sales
1       E003  Peter Brown   D001      Sales
2       E002   Jane Smith   D003      Admin
3       E004  Tom Johnson   D002         HR
4       E005   Rita Patel   D005        NaN
5        NaN          NaN   D004  Marketing

笛卡尔积连接

Pandas 中的笛卡尔积连接会在保留左侧 DataFrame 的顺序的同时,创建两个 DataFrame 的笛卡尔积。

例如,

import pandas as pd

# create dataframes from the dictionaries
data1 = {
    'EmployeeID' : ['E001', 'E002', 'E003', 'E004', 'E005'],
    'Name' : ['John Doe', 'Jane Smith', 'Peter Brown', 'Tom Johnson', 'Rita Patel'],
    'DeptID': ['D001', 'D003', 'D001', 'D002', 'D005'],
}
employees = pd.DataFrame(data1)

data2 = {
    'DeptID': ['D001', 'D002', 'D003','D004'],
    'DeptName': ['Sales', 'HR', 'Admin', 'Marketing']
}
departments = pd.DataFrame(data2)

# set DeptID as index for departments
departments.set_index('DeptID',inplace=True)

# cross join df_join = employees.join(departments, how = 'cross')
print(df_join)

输出

   EmployeeID         Name DeptID   DeptName
0        E001     John Doe   D001      Sales
1        E001     John Doe   D001         HR
2        E001     John Doe   D001      Admin
3        E001     John Doe   D001  Marketing
4        E002   Jane Smith   D003      Sales
5        E002   Jane Smith   D003         HR
6        E002   Jane Smith   D003      Admin
7        E002   Jane Smith   D003  Marketing
8        E003  Peter Brown   D001      Sales
9        E003  Peter Brown   D001         HR
10       E003  Peter Brown   D001      Admin
11       E003  Peter Brown   D001  Marketing
12       E004  Tom Johnson   D002      Sales
13       E004  Tom Johnson   D002         HR
14       E004  Tom Johnson   D002      Admin
15       E004  Tom Johnson   D002  Marketing
16       E005   Rita Patel   D005      Sales
17       E005   Rita Patel   D005         HR
18       E005   Rita Patel   D005      Admin
19       E005   Rita Patel   D005  Marketing

Join vs Merge vs Concat

在 Pandas 中有三种不同的方法可以组合 DataFrame

  • join():根据索引连接两个 DataFrame,默认执行左连接
  • merge():根据任何指定的列连接两个 DataFrame,默认执行内连接
  • concat():沿着垂直或水平轴堆叠两个 DataFrame

我们的高级学习平台,凭借十多年的经验和数千条反馈创建。

以前所未有的方式学习和提高您的编程技能。

试用 Programiz PRO
  • 交互式课程
  • 证书
  • AI 帮助
  • 2000+ 挑战