inner join 和join的区别_pandas中concat(), append(), merge()的区别和用法

文章目录

  • 三个函数的区别
    • concat()
    • append()
    • merge()
  • 三个函数各自的拓展用法
    • concat()
      • 连接多个DataFrame
      • 设置特定的键(key)
      • 横向合并两个DataFrame
    • append()
      • 连接多个DataFrame
    • merge()
      • 指定两个列名连接DataFrame
      • merge()的四种连接方式

1. 三个函数的区别

concat(), append(), merge()一般都是用来连接两个或者多个DataFrame对象。其中, concat(), append()默认用来纵向连接DataFrame对象, merge()用来横向连接DataFrame对象。

接下来我们来看看具体的例子。

1.1 concat()

concat()默认情况下是纵向连接两个DataFrame:

# 初始化df1
 

212db47bb08d54fa5b653e39d2e68d90.png
# 初始化df2
df2 = pd.DataFrame({'A': ['A4', 'A5', 'A6', 'A7'],
                        'B': ['B4', 'B5', 'B6', 'B7'],
                        'C': ['C4', 'C5', 'C6', 'C7'],
                        'D': ['D4', 'D5', 'D6', 'D7']})
df2

ad5271f04fff9a1d91cfce76170e121f.png
# concat : 纵向连接df1和df2。
result = pd.concat([df1, df2])
result

84d1c5da736fb84beaf831991b9259da.png

我们看到df1, df2纵向合并在了一起。但也注意到, 因为concat()保留了每个子DataFrame的index, 所以合并之后的DataFrame中, 每个index出现了两次。

我们可以通过设置ignore_index=False来解决这个问题:

result = pd.concat([df1, df2], ignore_index=True)
result

88ab4ec9c12b4f1e254660e23adf16b9.png

可以看到, 设置了ignore_index=True之后, 合并之后的DataFrame对index重新进行了排序。

1.2 append()

append()的默认操作效果跟concat()相同, 都是实现两个DataFrame的纵向连接。事实上可以把它看做concat()的早期版本:

 df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],
                        'B': ['B0', 'B1', 'B2', 'B3'],
                        'C': ['C0', 'C1', 'C2', 'C3'],
                        'D': ['D0', 'D1', 'D2', 'D3']})
 df1

272f86586e9f9093c93ad33499c728b2.png
df2 = pd.DataFrame({'A': ['A4', 'A5', 'A6', 'A7'],
                        'B': ['B4', 'B5', 'B6', 'B7'],
                        'C': ['C4', 'C5', 'C6', 'C7'],
                        'D': ['D4', 'D5', 'D6', 'D7']})
df2

cef8ec67fd3c08bcd3e3535e6da46f19.png
result = df1.append(df2)
result

2f1a3717fe11d80d18f9f6de23e1f72f.png

可以看到我们得到了跟concat()默认操作同样的结果。因为append()也保留了每个子DataFrame的index, 所以合并之后的DataFrame中, 每个index出现了两次。

我们同样可以通过设置ignore_index=False来解决这个问题:

result = df1.append(df2, ignore_index=True)
result

200d5180c201cc9babfefe7ca3e3f26d.png

1.3 merge()

merge()的默认操作是横向连接两个DataFrame对象:

left = pd.DataFrame({'key': ['K0', 'K1', 'K2'],
                     'A': ['A0', 'A1', 'A2'],
                     'B': ['B0', 'B1', 'B2']})
left

224a82cbef9f752af71b55dd1e4779f0.png
right = pd.DataFrame({'key': ['K1', 'K2', 'K3'],
                       'C': ['C1', 'C2', 'C3'],
                       'D': ['D1', 'D2', 'D3']}) 
right

180ea72d6c7f1a38f89f7b7ee21a2143.png
#  横向合并left和right两个子DataFrame。
## on='key' :  把两个子DataFrame中key列相同的值连接到一行上。
result = pd.merge(left, right, on='key')
result

3b1ea98e0513d3c5672ccc29e397bfd0.png

从上面的结果可以看出, merge()方法把两个子DataFrame中key列相同的值连接到了一行上, 并且删去了key列值不相同的行。

如果想保留key列值不相同的行, 可以添加上how='outer'参数:

# how: 指定两个子DataFrame的连接方式, 
result = pd.merge(left, right, on='key', how='outer')
result

c776dea3cd62656694f084791d50e1a7.png

2. 三个函数各自的拓展用法

2.1 concat()

  • 2.1.1 连接多个DataFrame

concat()可以一次性连接3个或者3个以上的DataFrame:

 df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],
                        'B': ['B0', 'B1', 'B2', 'B3'],
                        'C': ['C0', 'C1', 'C2', 'C3'],
                        'D': ['D0', 'D1', 'D2', 'D3']})
 df1

7ee5db074fca6c009b528347d232b43d.png
df2 = pd.DataFrame({'A': ['A4', 'A5', 'A6', 'A7'],
                        'B': ['B4', 'B5', 'B6', 'B7'],
                        'C': ['C4', 'C5', 'C6', 'C7'],
                        'D': ['D4', 'D5', 'D6', 'D7']})
df2

132bf82211112445a41943a3f5f4f522.png
df3 = pd.DataFrame({'A': ['A8', 'A9', 'A10', 'A11'],
                     'B': ['B8', 'B9', 'B10', 'B11'],
                      'C': ['C8', 'C9', 'C10', 'C11'],
                      'D': ['D8', 'D9', 'D10', 'D11']})
df3

6644392cb1198f70a4ba6f1efe80bc1d.png
result = pd.concat([df1, df2, df3])
result

bc9c32120ff6fcbd4dc205f45086c1c8.png
  • 2.1.2 设置特定的键(key)

有时候我们需要区分合并之后的DataFrame里, 哪些数据是来自df1的,哪些数据是来自df2的。这个时候我们可以给它们设置一个特定的键(key), 相当于给它们起个名字, 这样我们就可以把它们区分开来了。

# 为每个子DataFrame设置一个特定的键(key)
result = pd.concat([df1, df2], keys=['df1', 'df2'])
result

7c284f679b9723a88a712a5bb0122c79.png

可以看到, 在合并后的DataFrame里, 我们用key把每个子DataFrame的数据标识了出来。

我们可以通过下面的方式取用某个子DataFrame的数据:

result.loc['df1']

342241f03bd90845f1cf796947cb83eb.png
  • 2.1.3 横向合并两个DataFrame

默认情况下, concat()纵向合并两个子DataFrame, 但通过设置axis=1参数之后, 我们也可以横向合并两个DataFrame。

 df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],
                        'B': ['B0', 'B1', 'B2', 'B3'],
                        'C': ['C0', 'C1', 'C2', 'C3'],
                        'D': ['D0', 'D1', 'D2', 'D3']})
 df1

0d9639f9091eb10767f5bf131ef9df60.png
# 准备一组新的数据df4
df4 = pd.DataFrame({'B': ['B2', 'B3', 'B6', 'B7'],
                     'D': ['D2', 'D3', 'D6', 'D7'],
                     'F': ['F2', 'F3', 'F6', 'F7']},
                    index=[2, 3, 6, 7])
df4

1540e7005ce5e02a7ce1e7646550accd.png
result = pd.concat([df1, df4], axis=1)
result

a449f608aaf018524ecfd58180868fde.png

从上面的结果可以看到, 设置了axis=1之后, df1和df4两个DataFrame横向地结合在了一起。两个DataFrame有着相同index的行连成了一行, index不相同的行各自占一行的内容。

如果只想保留有着相同index的行, 可以添加上join=‘inner’参数:

result = pd.concat([df1, df4], axis=1, join='inner')
result

89442e83115f4b241fb3a943841512ee.png

如果想保留某个子DataFrame的index所在的行, 比如df1中index为0-3的行, 可以加上join_axes=[df1.index]参数:

result = pd.concat([df1, df4], axis=1, join_axes=[df1.index])
result

7e967854ac77ece0ac5bd8fc6a88de0a.png

2.2 append()

  • 2.2.1 连接多个DataFrame

和concat()一样, append()也可以一次性连接3个或者3个以上的DataFrame:

 df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],
                        'B': ['B0', 'B1', 'B2', 'B3'],
                        'C': ['C0', 'C1', 'C2', 'C3'],
                        'D': ['D0', 'D1', 'D2', 'D3']})
 df1

31e407e7fa5cb224150cdedd00b26b92.png
df2 = pd.DataFrame({'A': ['A4', 'A5', 'A6', 'A7'],
                        'B': ['B4', 'B5', 'B6', 'B7'],
                        'C': ['C4', 'C5', 'C6', 'C7'],
                        'D': ['D4', 'D5', 'D6', 'D7']})
df2merge()

f8bfa754feb2782e076e7af3417bcf41.png
df3 = pd.DataFrame({'A': ['A8', 'A9', 'A10', 'A11'],
                     'B': ['B8', 'B9', 'B10', 'B11'],
                      'C': ['C8', 'C9', 'C10', 'C11'],
                      'D': ['D8', 'D9', 'D10', 'D11']})
df3

c600afceb95a90925793ebb64a44352d.png
result = df1.append([df2, df3])
result

65ab417cfa4d5f83ad3f7f35e5fa2cb0.png

2.3 merge()

  • 2.3.1 指定两个列名连接DataFrame

我们可以在on参数里指定两个或者两个以上的列名对DataFrame进行连接:

left = pd.DataFrame({'key1': ['K0', 'K0', 'K1', 'K2'],
                         'key2': ['K0', 'K1', 'K0', 'K1'],
                         'A': ['A0', 'A1', 'A2', 'A3'],
                         'B': ['B0', 'B1', 'B2', 'B3']})
left

2bc8080d963d2c4d2f931acfe33d34e2.png
right = pd.DataFrame({'key1': ['K0', 'K1', 'K1', 'K2'],
                          'key2': ['K0', 'K0', 'K0', 'K0'],
                          'C': ['C0', 'C1', 'C2', 'C3'],
                          'D': ['D0', 'D1', 'D2', 'D3']})
right

558cdf70f994361f987613799d2a8452.png
result = pd.merge(left, right, on=['key1', 'key2'])
result

31fcb9025c551cefb3dfd0860d900c96.png

在上面的例子里, 我们在on参数里设置了key1, key2两个值, 于是在连接left和right两个DataFrame的时候, 会把key1, key2都相等的行连在一起, 而key1, key2不完全相等的行则会被舍弃掉。

  • 2.3.2 merge()的四种连接方式

merge()的how参数可以设置DataFrame的四种连接方式:左连接(left), 右连接(right), 外连接(outer), 内连接(inner)。

内连接(inner)是merge()的默认连接方式, 当how中不设置任何参数的时候, merge()用的是内连接(inner)方式。 也就是我们在上面的例子中所看到的, key值不完全相同的行便不会显示在最终的结果里 :

left = pd.DataFrame({'key1': ['K0', 'K0', 'K1', 'K2'],
                         'key2': ['K0', 'K1', 'K0', 'K1'],
                         'A': ['A0', 'A1', 'A2', 'A3'],
                         'B': ['B0', 'B1', 'B2', 'B3']})
left

d9bbe9a5fe38e35d4704f2d3436666a8.png
right = pd.DataFrame({'key1': ['K0', 'K1', 'K1', 'K2'],
                          'key2': ['K0', 'K0', 'K0', 'K0'],
                          'C': ['C0', 'C1', 'C2', 'C3'],
                          'D': ['D0', 'D1', 'D2', 'D3']})
right

ca0748e72699a0749952ad82f04c2098.png
result = pd.merge(left, right, on=['key1', 'key2'],
                 how='inner')
result

9ad8f3c8010fdb7be606b3891df98c00.png

外连接(outer)则会保留两个DataFrame中所有的行:

result = pd.merge(left, right, on=['key1', 'key2'],
                  how='outer')
result

125f27087e578b025fb026ad75b9238b.png

左连接(left)则会保留左边的子DataFrame中所有的行:

result = pd.merge(left, right, on=['key1', 'key2'],
                  how='left')
result

5f83e092779628e6ba401fecb8132c98.png

右连接(right)则会保留右边的子DataFrame中所有的行:

result = pd.merge(left, right, on=['key1', 'key2'],
                  how='right')
result

8b8fb7dd5f8bd2a6329dd4487276f7d3.png

以上便是本篇文章的内容。

参考资料:

https://pandas.pydata.org/pandas-docs/stable/user_guide/merging.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值