import numpy as np
import pandas as pd
Pandas 中提供了 merge
函数实现关系型合并。
='inner', on=None, left_on=None, right_on=None,
df1.merge(df2, how=False, right_index=False, sort=False,
left_index=('_x', '_y'), copy=None, indicator=False, validate=None) suffixes
主要参数含义:
df2
:待合并的 DataFrame 或者 Serieshow
:合并方式left
:左连接,合并后显示 df1 的所有行right
:右连接,合并后显示 df2 的所有行outer
:外连接,合并后显示 df1、df2 的所有行inner
:内连接,合并后显示 df1、df2 的共有行cross
:交叉连接,合并后显示 df1、df2 的笛卡尔积
on
:列名或者索引名,df1 和 df2 合并的键left_on
、right_on
:当 df1 和 df2 待合并的键在表中的名称不一样时,可分别指定left_index
、right_index
:布尔变量,是否使用索引进行合并suffixes
:列表类型。如果两张表中有相同的列名,suffixes
为合并表的列名提供了后缀
# create some toy data
= pd.DataFrame({'Date': pd.date_range('2023-08-01', periods=5),
df1 'Company': ['A', 'B', 'C', 'D', 'E'],
'Close': [20, 23, 21, 22, 20]})
= pd.DataFrame({'Date': pd.date_range('2023-08-03', periods=5),
df2 'Firm': ['C', 'D', 'E', 'F', 'G'],
'Volume': [100, 101, 120, 110, 105]})
df1
Date | Company | Close | |
---|---|---|---|
0 | 2023-08-01 | A | 20 |
1 | 2023-08-02 | B | 23 |
2 | 2023-08-03 | C | 21 |
3 | 2023-08-04 | D | 22 |
4 | 2023-08-05 | E | 20 |
df2
Date | Firm | Volume | |
---|---|---|---|
0 | 2023-08-03 | C | 100 |
1 | 2023-08-04 | D | 101 |
2 | 2023-08-05 | E | 120 |
3 | 2023-08-06 | F | 110 |
4 | 2023-08-07 | G | 105 |
merge
默认使用内连接(inner
),如果不指定合并的键,默认使用两张表中共同的列作合并,df1 和 df2 共同的列是 date,合并后显示共有的 date:
df1.merge(df2)
Date | Company | Close | Firm | Volume | |
---|---|---|---|---|---|
0 | 2023-08-03 | C | 21 | C | 100 |
1 | 2023-08-04 | D | 22 | D | 101 |
2 | 2023-08-05 | E | 20 | E | 120 |
使用 left_on
和 right_on
参数可以指定两张表做合并的键,下面指定使用 df1 中的 Company 和 df2 中的 Firm 来做合并:
df1.merge(df2, ='Company',
left_on='Firm') right_on
Date_x | Company | Close | Date_y | Firm | Volume | |
---|---|---|---|---|---|---|
0 | 2023-08-03 | C | 21 | 2023-08-03 | C | 100 |
1 | 2023-08-04 | D | 22 | 2023-08-04 | D | 101 |
2 | 2023-08-05 | E | 20 | 2023-08-05 | E | 120 |
由于 df1 和 df2 中都有 Date 这一列,为了加以区分,Pandas 自动给两张表中的 Date 加了后缀,我们可以使用 suffixes
参数来自定义后缀:
df1.merge(df2,='Company',
left_on='Firm',
right_on=['_1', '_2']) suffixes
Date_1 | Company | Close | Date_2 | Firm | Volume | |
---|---|---|---|---|---|---|
0 | 2023-08-03 | C | 21 | 2023-08-03 | C | 100 |
1 | 2023-08-04 | D | 22 | 2023-08-04 | D | 101 |
2 | 2023-08-05 | E | 20 | 2023-08-05 | E | 120 |
但是既然两张表里都有 Date 这一列,最好的方式是使用多键合并:
df1.merge(df2, =['Date', 'Company'],
left_on=['Date','Firm']) right_on
Date | Company | Close | Firm | Volume | |
---|---|---|---|---|---|
0 | 2023-08-03 | C | 21 | C | 100 |
1 | 2023-08-04 | D | 22 | D | 101 |
2 | 2023-08-05 | E | 20 | E | 120 |
使用 how
参数可以指定合并的方式,left
表示左连接,合并后显示 df1 的所有行,df2 中没有 2023-08-01 和 2023-08-02 两天,则对应的 Firm 和 Volume 显示为空值。
='left') df1.merge(df2, how
Date | Company | Close | Firm | Volume | |
---|---|---|---|---|---|
0 | 2023-08-01 | A | 20 | NaN | NaN |
1 | 2023-08-02 | B | 23 | NaN | NaN |
2 | 2023-08-03 | C | 21 | C | 100.0 |
3 | 2023-08-04 | D | 22 | D | 101.0 |
4 | 2023-08-05 | E | 20 | E | 120.0 |
right
表示右连接,合并后显示 df2 的所有行:
='right') df1.merge(df2, how
Date | Company | Close | Firm | Volume | |
---|---|---|---|---|---|
0 | 2023-08-03 | C | 21.0 | C | 100 |
1 | 2023-08-04 | D | 22.0 | D | 101 |
2 | 2023-08-05 | E | 20.0 | E | 120 |
3 | 2023-08-06 | NaN | NaN | F | 110 |
4 | 2023-08-07 | NaN | NaN | G | 105 |
outer
表示外连接,合并后显示 df1 和 df2 的所有行:
='outer') df1.merge(df2, how
Date | Company | Close | Firm | Volume | |
---|---|---|---|---|---|
0 | 2023-08-01 | A | 20.0 | NaN | NaN |
1 | 2023-08-02 | B | 23.0 | NaN | NaN |
2 | 2023-08-03 | C | 21.0 | C | 100.0 |
3 | 2023-08-04 | D | 22.0 | D | 101.0 |
4 | 2023-08-05 | E | 20.0 | E | 120.0 |
5 | 2023-08-06 | NaN | NaN | F | 110.0 |
6 | 2023-08-07 | NaN | NaN | G | 105.0 |
cross
表示交叉合并,合并后显示 df1 和 df2 的笛卡尔积:
='cross') df1.merge(df2, how
Date_x | Company | Close | Date_y | Firm | Volume | |
---|---|---|---|---|---|---|
0 | 2023-08-01 | A | 20 | 2023-08-03 | C | 100 |
1 | 2023-08-01 | A | 20 | 2023-08-04 | D | 101 |
2 | 2023-08-01 | A | 20 | 2023-08-05 | E | 120 |
3 | 2023-08-01 | A | 20 | 2023-08-06 | F | 110 |
4 | 2023-08-01 | A | 20 | 2023-08-07 | G | 105 |
5 | 2023-08-02 | B | 23 | 2023-08-03 | C | 100 |
6 | 2023-08-02 | B | 23 | 2023-08-04 | D | 101 |
7 | 2023-08-02 | B | 23 | 2023-08-05 | E | 120 |
8 | 2023-08-02 | B | 23 | 2023-08-06 | F | 110 |
9 | 2023-08-02 | B | 23 | 2023-08-07 | G | 105 |
10 | 2023-08-03 | C | 21 | 2023-08-03 | C | 100 |
11 | 2023-08-03 | C | 21 | 2023-08-04 | D | 101 |
12 | 2023-08-03 | C | 21 | 2023-08-05 | E | 120 |
13 | 2023-08-03 | C | 21 | 2023-08-06 | F | 110 |
14 | 2023-08-03 | C | 21 | 2023-08-07 | G | 105 |
15 | 2023-08-04 | D | 22 | 2023-08-03 | C | 100 |
16 | 2023-08-04 | D | 22 | 2023-08-04 | D | 101 |
17 | 2023-08-04 | D | 22 | 2023-08-05 | E | 120 |
18 | 2023-08-04 | D | 22 | 2023-08-06 | F | 110 |
19 | 2023-08-04 | D | 22 | 2023-08-07 | G | 105 |
20 | 2023-08-05 | E | 20 | 2023-08-03 | C | 100 |
21 | 2023-08-05 | E | 20 | 2023-08-04 | D | 101 |
22 | 2023-08-05 | E | 20 | 2023-08-05 | E | 120 |
23 | 2023-08-05 | E | 20 | 2023-08-06 | F | 110 |
24 | 2023-08-05 | E | 20 | 2023-08-07 | G | 105 |