《对比Excel,轻松学习Python数据分析》读书笔记------多表拼接

11 多表拼接

11.1 表的横向拼接

表的横向拼接,指的是将多个表按照某些公共列(往往具有索引性质)进行横向拼接。

Excel

主要通过VLOOKUP函数实现。

已知表1,表2有公共列,通过VLOOKUP函数,可以找到表1的公共列中的某个值在表2中的那一行的其他数据。

=VLOOKUP(lookup_value,table_array,col_index_num,[range_lookup])
  • lookup_value设置表1的公共列中的某个值,用于查找。称为查阅值。

  • table_array设置表2的查询区域。要使得公共列为该区域中的第1列,而要查找的数据在该区域中

  • col_index_num设置要查找的数据在table_array中的列序号。从1开始

  • [range_lookup]设置查找模式。1TRUE设置近似模式。0FALSE设置精确模式。可选。

如:

=VLOOKUP(C2,Sheet3!$A$1:$D$4,2)     
=VLOOKUP(C2,Sheet3!$A$1:$D$4,3)
=VLOOKUP(C2,Sheet3!$A$1:$D$4,4)
  • C2为"学校编号"列的第一个值
  • Sheet3!$A$1:$D$4为以"学校编号"列为第一列的表2区域
  • 2,3,4分别代表着表2中的"学校名称",“地区”,"地区一本线"列

分别对整列填充公式后的效果:

在这里插入图片描述

Python

pd.merge(left:'DataFrame | Series',
         right: 'DataFrame | Series',
         how: 'str' = 'inner',
         on: 'IndexLabel | None' = None,
         left_on: 'IndexLabel | None' = None,
         right_on: 'IndexLabel | None' = None,
         left_index: 'bool' = False,
         right_index: 'bool' = False,
         sort: 'bool' = False,
         suffixes: 'Suffixes' = ('_x', '_y')
        )
df.merge(right: 'DataFrame | Series',
         how: 'str' = 'inner',
         on: 'IndexLabel | None' = None,
         left_on: 'IndexLabel | None' = None,
         right_on: 'IndexLabel | None' = None,
         left_index: 'bool' = False,
         right_index: 'bool' = False,
         sort: 'bool' = False,
         suffixes: 'Suffixes' = ('_x', '_y')
        )
  • left设置要拼接的左表。
  • right设置要拼接的右表。
  • how设置拼接方式。left左连接,right右连接,outer外连接,inner内连接,cross交叉连接
  • on设置公共列
  • left_on设置左表公共列的名称。
  • right_on设置右表公共列的名称。
  • left_index设置启用左表行索引作为公共列。
  • right_index设置启用右表行索引作为公共列。
  • sort设置是否对结果排序。
  • suffixes设置两表连接后重复列的下标。
11.1.1 一对一连接
a=pd.DataFrame({
    "公共列":["a","b","c","d"],
    "值":[1,2,3,4]
})

b=pd.DataFrame({
    "值":[2,4,6,8],
    "公共列":["a","b","c","d"],
})

print(a.merge(b,on="公共列"))
"""
  公共列  值_x  值_y
0   a    1    2
1   b    2    4
2   c    3    6
3   d    4    8
"""
11.1.2 左连接

以左表为基础,将右表连接至左表。

如果左表公共列的值多,右表少的值用空值填充。如:

x=pd.DataFrame({
    "公共列":["a","b","c","d","e","f"],
    "值":[1,2,3,4,5,6]
})

y=pd.DataFrame({
    "值":[2,4,6,8],
    "公共列":["a","b","c","d"],
})

print(x.merge(y,how="left",on="公共列"))
"""
  公共列  值_x  值_y
0   a    1  2.0
1   b    2  4.0
2   c    3  6.0
3   d    4  8.0
4   e    5  NaN
5   f    6  NaN
"""

如果左表公共列的值少,右表多的值忽略。如:

x = pd.DataFrame({"公共列": ["a", "b", "c", "d"], "值": [1, 2, 3, 4]})

y = pd.DataFrame({
    "值": [2, 4, 6, 8, 10, 12],
    "公共列": ["a", "b", "c", "d", "e", "f"],
})

print(x.merge(y, how="left", on="公共列"))
"""
  公共列  值_x  值_y
0   a    1    2
1   b    2    4
2   c    3    6
3   d    4    8
"""
11.1.3 右连接

类似于左连接。

以右表为基础,将左表连接至右表。

如果右表公共列的值多,左表少的值用空值填充。

如果右表公共列的值少,左表多的值忽略。

如:

x = pd.DataFrame({"公共列": ["a", "b", "c", "d"], "值": [1, 2, 3, 4]})

y = pd.DataFrame({
    "值": [2, 4, 6, 8, 10, 12],
    "公共列": ["a", "b", "c", "d", "e", "f"],
})

print(x.merge(y, how="right", on="公共列"))
"""
  公共列  值_x  值_y
0   a  1.0    2
1   b  2.0    4
2   c  3.0    6
3   d  4.0    8
4   e  NaN   10
5   f  NaN   12
"""

print(y.merge(x,how="right",on="公共列"))
"""
   值_x 公共列  值_y
0    2   a    1
1    4   b    2
2    6   c    3
3    8   d    4
"""
11.1.4 内连接

取两表的公共列的公共值。即,取交集。

如:

x = pd.DataFrame({
    "公共列": ["a", "b", "c", "d", "e", "f"],
    "值": [1, 2, 3, 4, 5, 6]
})

y = pd.DataFrame({
    "值": [2, 4, 6, 8, 10, 12],
    "公共列": ["a", "b", "c", "d", "h", "i"],
})

print(x.merge(y, how="inner", on="公共列"))
"""
  公共列  值_x  值_y
0   a    1    2
1   b    2    4
2   c    3    6
3   d    4    8
"""
11.1.5 外连接

取两表的公共列的所有值。不是公共值的用空值填充。即,取并集。

如:

x = pd.DataFrame({
    "公共列": ["a", "b", "c", "d", "e", "f"],
    "值": [1, 2, 3, 4, 5, 6]
})

y = pd.DataFrame({
    "值": [2, 4, 6, 8, 10, 12],
    "公共列": ["a", "b", "c", "d", "h", "i"],
})

print(x.merge(y, how="outer", on="公共列"))
"""
  公共列  值_x   值_y
0   a  1.0   2.0
1   b  2.0   4.0
2   c  3.0   6.0
3   d  4.0   8.0
4   e  5.0   NaN
5   f  6.0   NaN
6   h  NaN  10.0
7   i  NaN  12.0
"""
11.1.6 交叉连接

直接取表 x x x的各行 x i x_i xi与表 y y y的各行 y j y_j yj的所有笛卡尔乘积组合( ( x i , y j ) (x_i,y_j) (xi,yj),生成一份总表。

此时不需要设置on,left_on,right_on,left_index,right_index的任意一项

如:

x = pd.DataFrame({"公共列": ["x_1", "x_2", "x_3", "x_4"], "值": [2, 4, 6, 8]})

y = pd.DataFrame({
    "值": [1, 3, 5],
    "公共列": ["y_1", "y_2", "y_3"],
})

print(x.merge(y, how="cross"))
"""
   公共列_x  值_x  值_y 公共列_y
0    x_1    2    1   y_1
1    x_1    2    3   y_2
2    x_1    2    5   y_3
3    x_2    4    1   y_1
4    x_2    4    3   y_2
5    x_2    4    5   y_3
6    x_3    6    1   y_1
7    x_3    6    3   y_2
8    x_3    6    5   y_3
9    x_4    8    1   y_1
10   x_4    8    3   y_2
11   x_4    8    5   y_3
"""

11.2 表的纵向拼接

表的纵向拼接,往往是把两张结构相同的表合并。

Excel

复制粘贴

Python

pd.concat(objs: 'Iterable[NDFrame] | Mapping[Hashable, NDFrame]',
          axis: 'Axis' = 0,
          join: 'str' = 'outer',
          ignore_index: 'bool' = False,
          keys=None,
          names=None,
          sort: 'bool' = False)
  • objs设置想要拼接的表们。

  • axis设置拼接的数据单位。

  • join设置数据的拼接方式。inner,outer可选

  • ignore_index设置是否重新生成数字新索引。

  • keys设置两表拼接后各子表对应数据的行索引。此时ignore_index必须为False,否则失效。

  • nameskeys行索引和数据区域设置名称。

  • sort设置是否给结果排序。

如:

x = pd.DataFrame({
    "列1": ["a", "b", "c", "d"],
    "列2": [1, 2, 3, 4],
    "列3": ["A", "B", "C", "D"],
    "列4": [1, 1, 1, 1]
})

y = pd.DataFrame({
    "列1": ["e", "f", "g", "h"],
    "列2": [5, 6, 7, 8],
    "列3": ["E", "F", "G", "H"],
    "列5": [2, 2, 2, 2]
})

print(pd.concat([x, y]))     # 直接纵向拼接,列使用外连接方式连接,即取并集
"""
  列1  列2 列3   列4   列5
0  a   1  A  1.0  NaN
1  b   2  B  1.0  NaN
2  c   3  C  1.0  NaN
3  d   4  D  1.0  NaN
0  e   5  E  NaN  2.0
1  f   6  F  NaN  2.0
2  g   7  G  NaN  2.0
3  h   8  H  NaN  2.0
"""

print(pd.concat([x, y], keys=["表x", "表y"], names=["表源", "数据"])) # 加索引
"""
      列1  列2 列3   列4   列5
表源 数据                    
表x 0   a   1  A  1.0  NaN
   1   b   2  B  1.0  NaN
   2   c   3  C  1.0  NaN
   3   d   4  D  1.0  NaN
表y 0   e   5  E  NaN  2.0
   1   f   6  F  NaN  2.0
   2   g   7  G  NaN  2.0
   3   h   8  H  NaN  2.0
"""

print(pd.concat([x, y], join="inner", ignore_index=True)) # 列使用内连接方式连接,即取交集
"""
  列1  列2 列3
0  a   1  A
1  b   2  B
2  c   3  C
3  d   4  D
4  e   5  E
5  f   6  F
6  g   7  G
7  h   8  H
"""

print(pd.concat([x,y],axis=1))   # 以列为拼接单位,变为横向连接
"""
  列1  列2 列3  列4 列1  列2 列3  列5
0  a   1  A   1  e   5  E   2
1  b   2  B   1  f   6  F   2
2  c   3  C   1  g   7  G   2
3  d   4  D   1  h   8  H   2
"""
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

木子希卡利

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值