这里是数据合并与连接的几种方法,分别为 merge、join、concat 和 append

目录

一、连接列:

(一)merge

1.基于列使用 how=' ' 定义连接方法,并使用 on=' column_name' 作为连接键

2.基于索引

(二)join

(三)concat

二、连接行

(一)concat

(二)append

三、数据堆叠

(一)vstack()

(二)hstack()


一、连接列:

(一)merge

        merge:默认基于共同列或基于索引进行横向连接,操作类似数据库使用 sql 将两张表合并成一张表

语法:merge(left/right, how=‘inner’, on=None, left_on=None, right_on=None, left_index=False, right_index=False, indicator=False)

        几个主要参数:

  • left,right:要merge的dataframe或者有名字的Series
  • how:连接的类型,‘left’,‘right’,‘outer’,‘inner’,默认内连接
  • on:join的key,要求left和right都需要有这个key才能用on,如果两个dataframe的列不一样,则用下面两个参数指定
  • left_on/right_on:在列名不同时,指定 left/right 的 df 或者 series 的 key
  • left_index,right_index:默认FALSE,设置为TRUE会使用 index,而不是column做连接
  • indicator:显示合并数据中数据的来源情况,为True时,它会自动给结果加一列“_merge",内容为right_only、left_only、both等,可用于数据的筛选和操作
  • sort:默认为True,将合并的数据进行排序,设置为False可以提高性能;
  • suffixes:字符串值组成的元组,用于指定当左右 DataFrame 存在相同列名时在列名后面附加的后缀名称,默认为('_x', '_y'),在两表有同名列又均想保留的情况可以使用;

1.基于列使用 how=' ' 定义连接方法,并使用 on=' column_name' 作为连接键

df1 = pd.DataFrame({'A':['A','B','B','C','D','E'],
					'B':['a','a','b','c','c','e'],
                    'v1':[1,1,2,3,3,1],
                    'v2':['low','medium','medium','high','low','high']})

   A  B  v1      v2
0  A  a   1     low
1  B  a   1  medium
2  B  b   2  medium
3  C  c   3    high
4  D  c   3     low
5  E  e   1    high
df2 = pd.DataFrame({'A':['A','A','B','F'],
					'B':['d','d','b','f'],
					'F':['apple','orange','peach','pear'],
                    'Level':['high','low','high','medium'],
                    'price':np.array([5,6,7,8])})

   A  B       F   Level  price
0  A  d   apple    high      5
1  A  d  orange     low      6
2  B  b   peach    high      7
3  F  f    pear  medium      8
# 内连接
df3 = pd.merge(df1,df2,on=['A','B'],how='inner')
print(df3)

   A  B  v1      v2      F Level  price
0  B  b   2  medium  peach  high      7

        解析:on=['A','B'] 即将 A、B 列作为连接键,当这个组合键相同时,进行连接,上面的 df1 和 df2 只有索引为2的一行数据是相同的,为 [B,b],因此,在有多列时,需要满足这几列都相同的数据才会进行连接

        此外,由于merge需指定连接的列,在两个 df 没有相同列需要用到索引时(见下方基于索引),应指定left_on、right_on 参数,否则会报错

        merge亦可进行纵向的列拼接,但一般来说我们有更好的方法

2.基于索引

  • left_on=' '+right_index=TRUE(右边的索引与左边的列值匹配)

  • right_on' '+left_index=TRUE(左边的索引与右边的列值匹配)

  • left_index=True+right_index=True(左右索引匹配)

# df1
df1 = pd.DataFrame({'A':['A','B','B','C','D','E'],
					'B':['a','a','b','c','c','e'],
                    'v1':[1,1,2,3,3,1],
                    'v2':['low','medium','medium','high','low','high']})

   A  B  v1      v2
0  A  a   1     low
1  B  a   1  medium
2  B  b   2  medium
3  C  c   3    high
4  D  c   3     low
5  E  e   1    high
# df2
df2 = pd.DataFrame({'A':['A','A','B','F'],
					'B':['d','d','b','f'],
					'F':['apple','orange','peach','pear'],
                    'Level':['high','low','high','medium'],
                    'price':np.array([5,6,7,8])})

   A  B       F   Level  price
0  A  d   apple    high      5
1  A  d  orange     low      6
2  B  b   peach    high      7
3  F  f    pear  medium      8

# 连接
# 左边的 index 与右边的 price 匹配
df7 = pd.merge(df1,df2,left_index=True,right_on='price')

  A_x B_x  v1    v2 A_y B_y      F Level  price
0   E   e   1  high   A   d  apple  high      5

(二)join

        join 和 merge 有相同的作用,不过 join 连接时默认使用行 index 进行连接,可以连接多个 DataFrame,而merge只能连接两个,并且 join 默认使用左外连接

        join 的参数与 merge 类似,主要有on、how、suffixes,但没有 left_on/right_on,参数 on 已经指定了作为索引的列,且必须是被匹配的 DataFrame 中存在列:

df1 = pd.DataFrame({'A':['A','B','B','C','D','E'],
                        'B':['a','a','b','c','c','e'],
                        'v1':[1,1,2,3,3,1],
                        'v2':['low','medium','medium','high','low','high']})

df2 = pd.DataFrame({'A':['A','A','B','F'],
                        'B':['d','d','b','f'],
                        'F':['apple','orange','peach','pear'],
                        'Level':['high','low','high','medium'],
                        'price':np.array([3,4,5,6])})

print(df1)
print('-----------------')
print(df2)

   A  B  v1      v2
0  A  a   1     low
1  B  a   1  medium
2  B  b   2  medium
3  C  c   3    high
4  D  c   3     low
5  E  e   1    high
-----------------
   A  B       F   Level  price
0  A  d   apple    high      3
1  A  d  orange     low      4
2  B  b   peach    high      5
3  F  f    pear  medium      6
# 左连接
df3=df1.join(df2.set_index('A'),on='A',how='inner',rsuffix='*') 
df3
# A,B列同名,需要区分,将 df2 的列加上'*'号后缀

# 这里将df1的 A 列作为索引与 df2 的 A 列匹配

	A	B	v1	v2	B*	F	Level	price
0	A	a	1	low	d	apple	high	3.0
0	A	a	1	low	d	orange	low	4.0
1	B	a	1	medium	b	peach	high	5.0
2	B	b	2	medium	b	peach	high	5.0
3	C	c	3	high	NaN	NaN	NaN	NaN
4	D	c	3	low	NaN	NaN	NaN	NaN
5	E	e	1	high	NaN	NaN	NaN	NaN

         join 可类似 merge 使用列标签连表,但该函数默认用左表的 on 列和右表的索引进行匹配,因此需要使用 df.set_index(' ').join() 指定某列作为索引

(三)concat

        将下方 concat() 中 axis 参数设为 1 即可

二、连接行

(一)concat

        如下两个dataframe

df1 = pd.DataFrame({'A':['A','B','B','C','D','E'],
                        'B':['a','a','b','c','c','e'],
                        'v1':[1,1,2,3,3,1],
                        'v2':['low','medium','medium','high','low','high']})

   A  B  v1      v2
0  A  a   1     low
1  B  a   1  medium
2  B  b   2  medium
3  C  c   3    high
4  D  c   3     low
5  E  e   1    high
df2 = pd.DataFrame({'A':['A','A','B','F'],
                        'B':['d','d','b','f'],
                        'F':['apple','orange','peach','pear'],
                        'Level':['high','low','high','medium'],
                        'price':np.array([3,4,5,6])})

   A  B       F   Level  price
0  A  d   apple    high      3
1  A  d  orange     low      4
2  B  b   peach    high      5
3  F  f    pear  medium      6

        concat 既可以进行纵向连接也可以进行横向连接,默认 axis=0 ,join='outer' 连接行的全外连接,在做行拼接时,行索引可以重复,列索引根据连接方式而定(outer 或 inner取并/交集),列拼接可由此类比

语法:pd.concat(objs, axis=0, join='outer', join_axes=None, ignore_index=False, keys=None, levels=None, names=None, verify_integrity=False, sort=None, copy=True)

  • objs:要拼接的对象,以列表形式传入
  • axis:0表示纵向拼接行,1表示横向拼接列
  • join:连接方式
  • ignore_index:默认False,即按照原来索引排序,设为True时忽略索引从1开始逐渐递增 
df3=pd.concat([df1,df2],axis=0,join='inner',ignore_index=True,)
print(df3)

   A  B
0  A  a
1  B  a
2  B  b
3  C  c
4  D  c
5  E  e
6  A  d
7  A  d
8  B  b
9  F  f
  • keys:可以是任意值的列表或数组、元组数组、数组列表,与 objs 对应可以进行表的溯源,也可以在有重复索引时做层次化索引(ignore_index优先生效)
df3=pd.concat([df1,df2],keys=['one','two'],axis=0,join='inner')
print(df3)

       A  B
one 0  A  a
    1  B  a
    2  B  b
    3  C  c
    4  D  c
    5  E  e
two 0  A  d
    1  A  d
    2  B  b
    3  F  f

(二)append

语法:dt._append(dt2,ignore_index=False,verify_integrity=False)

        append 属于简化版的concat,只能在 axis=0 方向上合并,即只能纵向拼接列,了解一下即可

  • ignore_index:默认False,这样行索引保持与原DataFrame中的行索引一致,即行索引重复不会受影响。若修改为True,结果的行索引会被重设为从0开始的整数索引。
  • verify_integrity:是否允许有重复标签默认False,添加的DataFrame中有相同的行索引时,可以保留原结果。若该参数为True,添加的新 DataFrame 中有相同的行索引时就会抛出ValueError报错。该参数设置为True可以避免结果中的行索引重复,但可能会导致添加失败,所以需要先观察原始数据。

        以上两个参数同时使用并不会报错,ignore_index 优先生效

df1 = pd.DataFrame({'A':['A','B','B','C','D','E'],
                        'B':['a','a','b','c','c','e'],
                        'v1':[1,1,2,3,3,1],
                        'v2':['low','medium','medium','high','low','high']})

   A  B  v1      v2
0  A  a   1     low
1  B  a   1  medium
2  B  b   2  medium
3  C  c   3    high
4  D  c   3     low
5  E  e   1    high
df2 = pd.DataFrame({'A':['A','A','B','F'],
                        'B':['d','d','b','f'],
                        'F':['apple','orange','peach','pear'],
                        'Level':['high','low','high','medium'],
                        'price':np.array([3,4,5,6])})

   A  B       F   Level  price
0  A  d   apple    high      3
1  A  d  orange     low      4
2  B  b   peach    high      5
3  F  f    pear  medium      6
df3=df1._append(df2,ignore_index=False)
print(df3)

   A  B   v1      v2       F   Level  price
0  A  a  1.0     low     NaN     NaN    NaN
1  B  a  1.0  medium     NaN     NaN    NaN
2  B  b  2.0  medium     NaN     NaN    NaN
3  C  c  3.0    high     NaN     NaN    NaN
4  D  c  3.0     low     NaN     NaN    NaN
5  E  e  1.0    high     NaN     NaN    NaN
0  A  d  NaN     NaN   apple    high    3.0
1  A  d  NaN     NaN  orange     low    4.0
2  B  b  NaN     NaN   peach    high    5.0
3  F  f  NaN     NaN    pear  medium    6.0

        可以看出,若有同名公共列,直接拼接最后列名会取并集,一个 dataframe 没有的列,在另一 dataframe 里其值为NaN

三、数据堆叠

        有时进行数据处理后会得到一个只有数值的数组,可以用以下几种方法进行直接堆叠,实际过程中注意此种方法没有连接条件,建议使用已排好序的数据

        这里以二维数据举例

(一)vstack()

import numpy as np

data1 = [[11, 12, 13], [14, 15, 16]]
data2 = [[41, 42, 43], [44, 45, 46]]

arr1 = np.array(data1)
arr1
arr2 = np.array(data2)
arr2

-----

array([[11, 12, 13],
       [14, 15, 16]])

array([[41, 42, 43],
       [44, 45, 46]])

        进行合并,vstack是进行行的合并

a = np.vstack((arr1, arr2))
print(a)

[[11 12 13]
 [14 15 16]
 [41 42 43]
 [44 45 46]]

(二)hstack()

b = np.hstack((arr1, arr2))
print(b)

-----

[[11 12 13 41 42 43]
 [14 15 16 44 45 46]]

         总结:在一维或二维甚至三维数组中,以上两种函数可视为直接在行/列上进行数据堆叠

待补充更新:melt、pivot、explode、pivot_table

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐