Pandas DataFrame连接表 几种连接方法的对比

网友投稿 1430 2022-09-07

Pandas DataFrame连接表 几种连接方法的对比

Pandas DataFrame连接表 几种连接方法的对比

可以通过多种方式将Pandas对象联合到一起

pandas.merge: 根据一个或多个键进行连接。类似SQL的连接操作pandas.concat:使对象在轴向上进行粘合或者‘堆叠’combine_first:将重叠的数据拼接在一起,使用一个对象中的值填充另一个对象中的缺失值

Pandas.DataFrame操作表连接有三种方式:merge, join, concat。下面就来说一说这三种方式的特性和用法。

先看两张表:

Screen Shot 2018-08-31 at 2.24.44 PM.png

Screen Shot 2018-08-31 at 2.24.52 PM.png

merge。相当于SQL中的JOIN。该函数的典型应用场景是,两张表有相同内容的列(即SQL中的键),现在我们想把两张表整合到一张表里。在此典型情况下,结果集的行数并没有增加,列数则为两个元数据的列数和减去连接键的数量。在数据处理的时候经常会遇到多个表单的合并问题,比如一个表单有​​user_id​​和​​age​​这两个字段,另一个表单有​​user_id​​和​​sex​​这两个字段,要把这两个表合并成只有​​user_id​​、​​age​​、​​sex​​三个字段的表。普通的拼接是做不到的,因为user_id每一行之间不是对应的。pandas中有个merge函数可以做到这个实用的功能。

1.1 参数说明:

merge(left, right, how='inner', on=None, left_on=None, right_on=None, left_index=False, right_index=False, sort=True, suffixes=('_x', '_y'), copy=True, indicator=False)

left与right:两个不同的DataFrame how:指的是合并(连接)的方式有inner(内连接),left(左外连接),right(右外连接),outer(全外连接);默认为inner! on : 指的是用于连接的列索引名称。必须存在右右两个DataFrame对象中,如果没有指定且其他参数也未指定则以两个DataFrame的列名交集做为连接键 left_on:左则DataFrame中用作连接键的列名;这个参数中左右列名不相同,但代表的含义相同时非常有用。 right_on:右则DataFrame中用作 连接键的列名 left_index:使用左则DataFrame中的行索引做为连接键,用到这个参数时,就有点类似于接下来要说的JOIN函数了。 right_index:使用右则DataFrame中的行索引做为连接键 sort:默认为True,将合并的数据进行排序。在大多数情况下设置为False可以提高性能 suffixes:字符串值组成的元组,用于指定当左右DataFrame存在相同列名时在列名后面附加的后缀名称,默认为('_x','_y') copy:默认为True,总是将数据复制到数据结构中;大多数情况下设置为False可以提高性能 indicator:在 0.17.0中还增加了一个显示合并数据中来源情况;如只来自己于左边(left_only)、两者(both)

1.2 merge的特征 1.2.1 默认以重叠列名当做链接键 1.2.2 默认是INNER JOIN。 1.2.3 可以多键连接,'on'参数后传入多键列表即可 1.2.4 如果两个对象的列表不同,可以用left_on, right_on指定。 1.2.5 也可以用行索引当连接键,使用参数left_index=True, right_index=True. 但是这种情况下最好用JOIN

现在来看例子: 开头介绍的两张表除了列名有重叠,内容并没有重叠的地方,所以并不是典型的merge场景。但是,用merge能不能合并呢?也可以。 如果用merge:pd.merge(df1, df2),会得到一张空表 必须指定行索引参数left_index, right_index:

pd.merge(df1, df2, left_index=True, right_index=True, how='left')

Screen Shot 2018-08-31 at 2.30.56 PM.png

这种是「非典型」应用,这种表的场景,更多的时候我们用JOIN函数来实现:

JOIN 拼接列,主要用于基于行索引上的合并。

只要两个表列名不同,不加任何参数就可以直接用。如果两个表有重复的列名,需指定lsuffix, rsuffix参数。其中参数的意义与merge方法基本相同,只是join方法默认为左外连接how=left

df1.join(df2, lsuffix='_l', rsuffix='_r') # 列名重复的时候需要指定lsuffix, rsuffix参数

Screen Shot 2018-08-31 at 3.10.52 PM.png

JOIN最适合的情况是基于行索引,上述例子因为列名有重复(即使内容没有重复),所以必须在JOIN的时候设置lsuffix, rsuffix参数,否则会报错。 如果列名不重复,则直接用' df1.join(df2) '即可。

但是! 如果我们想用JOIN实现基于列索引的合并,也是完全可以的。请注意以下的讨论全是关于用JOIN实现列索引合并的,即如何正确使用JOIN函数中的「ON」参数。 用JOIN实现基于列索引的合并主要考虑三种情况:

列名不同,列内容有相同列名相同,列内容有相同列名不同,列内容也不同

(1) 列名不同,列内容有相同,需要用到 l.join(r.set_index(key of r), on='key of l')

left = pd.DataFrame({'key1': ['foo', 'bar1'], 'lval': [1, 2]})right = pd.DataFrame({'key2': ['foo', 'bar'], 'rval': [4, 5]})left.join(right.set_index('key2'), on='key1')

Screen Shot 2018-08-31 at 4.05.30 PM.png

这种JOIN的写法等同于前面提到的merge设置left_on,right_on。

pd.merge(left, right,left_on='key1', right_on='key2') # 列名不同,但内容有相同可以当键

Screen Shot 2018-08-31 at 4.10.38 PM.png

因为merge默认是内连接,所以返回的结果只有一行,而JOIN返回的结果是以左表的key列为准,有两行。

(2)列名相同,内容有相同,需要用到l.join(r.set_index(key), on='key')。

left = pd.DataFrame({'key': ['foo', 'bar1'], 'lval': [1, 2]})right = pd.DataFrame({'key': ['foo', 'bar'], 'rval': [4, 5]})left.join(right.set_index('key'), on='key',lsuffix='_l', rsuffix='_r')

Screen Shot 2018-08-31 at 4.18.25 PM.png

这种JOIN的写法等同于前面提到的merge设置不带任何参数,而且这种情况下merge会去掉重复的列

pd.merge(left, right) # 列名不同,但内容有相同,所以依然可以作为键来用

Screen Shot 2018-08-31 at 4.20.42 PM.png

同样,因为merge默认是内连接,所以返回的结果只有一行,而JOIN返回的结果是以左表的key列为准,有两行。

特别注意,即使列名相同了,也必须用到' set_index(key)' 否则连接集会显示如下:

left.join(right,on='key',lsuffix='_l', rsuffix='_r')

Screen Shot 2018-08-31 at 4.34.59 PM.png

另外值得注意的一点,不指定'ON= '参数的情况下,JOIN是按行索引连接,也就是简单的水平连接两个表,不对列进行任何操作。如下代码返回的结果:

left.join(right,lsuffix='_l', rsuffix='_r')

Screen Shot 2018-08-31 at 4.25.30 PM.png

这个结果其实和用concat进行行操作是一模一样的:

pd.concat([left, right], axis=1)

(3)列名不同,内容也不同 这种情况是典型的行索引,不能用JOIN的ON参数进行列连接。

concat 轴向连接。就是单纯地把两个表拼在一起,这个过程也被称作绑定(binding)或堆叠(stacking)。因此可以想见,这个函数的关键参数应该是 axis,用于指定连接的轴向。axis=1 在行中操作,axis=0是在列中操作。默认是axis=0,即垂直堆叠。

df1=pd.DataFrame(np.random.randn(3,4),columns=['a','b','c','d'])df2=pd.DataFrame(np.random.randn(2,3),columns=['b','d','a'])pd.concat([df1, df2], axis=1) # 对行操作,相当于水平连接

注意到这里,左表和右表没有一个单元格是一样的,只是按照行索引水平堆在了一起,所以可以理解为相当于

pd.merge(df1,df2,left_index=True,right_index=True,how='outer')

或者

df1.join(df2, lsuffix="_l")

效果都是生成这样一张表

Screen Shot 2018-08-31 at 1.24.10 PM.png

最后看看CONCAT的垂直堆叠。垂直堆叠就是axis=0,这种情况下有个参数比较特殊,叫' ignore_index= ',默认情况下是False。如果设成了True,就是把结果的合并表重新编排行索引。否则,行索引还是原来两个表里的值,比如"0,1,2,0,1"

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

Screen Shot 2018-08-31 at 1.26.39 PM.png

如果两张表的列名都不相同,垂直堆叠会生扩展不同的列,生成一张更宽的表。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:解决Windows10运行VMware Workstation出现与Device Guard不兼容导致无法运行与创建虚拟机问题
下一篇:gif动态图片生成器,多张图片组合后生成动图...(多张图片怎么做成gif动态视频)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~