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 df1 和 df2。
在这里,我们在两个 DataFrame 中都指定了 index= ['K0', 'K1', 'K2', 'K3']
。这是为了提供一个通用的索引列,我们可以在此基础上执行 join 操作。
join() 语法
Pandas 中 join()
方法的语法是
df1.join(df2, on=None, how='left', lsuffix='', rsuffix='', sort=False)
这里,
df1
:第一个 DataFramedf2
:要连接到第一个 DataFrame 的 DataFrameon(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 employees 和 departments 执行了 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')
在这一行中,我们使用了带有 lsuffix
和 rsuffix
的 on
参数。
两个 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