pandas 之表的连接操作

问题

在分析数据时,遇到了要处理多个dataframe按照关键词user_id连接的需求,在sql中只要多个表left join on 就可以了,那么在pandas中怎么操作呢?

DataFrame中的表连接方式

dataframe主要有三个函数可以用来做表的连接,分别是join、merge、concat,下面分别介绍这三个DataFrame的用法。

join

1
DataFrame.join(other, on=None, how='left', lsuffix='', rsuffix='', sort=False)

通过列或者索引join “other” dataframe, 能高效的连接多个dataframe。

参数:

  • other:一个dataframe,或者是dataframe的list
  • on:列或索引名,或者是连接关键词的list
  • how:连接方式,可选{‘left’,’right’, ‘outer’, ‘inner’}, 默认值: ‘left’
  • lsuffix:左表交叉列的别名
  • rsuffix:右表交叉列的别名
  • sort:布尔值,是否按照连接关键词排序,默认为False

注意:多表连接只能通过索引,否则会报错

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-35-29a230cbe380> in <module>
----> 1 oned_beh_UserCou.join([threed_beh_UserCou.reset_index(),sixd_beh_UserCou.reset_index],how='left',on='user_id')

/usr/local/lib/python3.5/dist-packages/pandas/core/frame.py in join(self, other, on, how, lsuffix, rsuffix, sort)
5291 # For SparseDataFrame's benefit
5292 return self._join_compat(other, on=on, how=how, lsuffix=lsuffix,
-> 5293 rsuffix=rsuffix, sort=sort)
5294
5295 def _join_compat(self, other, on=None, how='left', lsuffix='', rsuffix='',

/usr/local/lib/python3.5/dist-packages/pandas/core/frame.py in _join_compat(self, other, on, how, lsuffix, rsuffix, sort)
5309 else:
5310 if on is not None:
-> 5311 raise ValueError('Joining multiple DataFrames only supported'
5312 ' for joining on index')
5313

ValueError: Joining multiple DataFrames only supported for joining on index

但是当对dataframe进行groupby、reset_index等操作后,此时的index可能并不是我们想要的索引列。可以通过以下函数来重置index:

1
2
3
pandas.DataFrame.reset_index()
pandas.DataFrame.set_index("",drop=True)
pandas.Series.reset_index()

merge

1
DataFrame.merge(right, how='inner', on=None, left_on=None, right_on=None, left_index=False, right_index=False, sort=False, suffixes=('_x', '_y'), copy=True, indicator=False, validate=None)[source]

merge类似于数据库中的join操作(database-style join),如果两表连接的字段是column,dataframe的index会被省略,如果是索引和索引或者索引和column的链接,最后仍会保留index

参数

  • right:连接的另一个dataframe
  • how: 连接方式,可选{‘left’,’right’, ‘outer’, ‘inner’}, 默认值: ‘inner’
  • on: 表的连接字段,column name 或者index name,这个字段必须出现在连接的两个dataframe中,如果该参数值为None,并且不是按照index连接,则表的连接字段为两个dataframe的公共字段
  • left_on: 左dataframe的连接column或index名,list或者array-like
  • right_on: 右dataframe的连接column或index名,list或者array-like
  • left_index: 布尔值,默认为False,使用左dataframe的index作为join的字段
  • right_index: 同left_index
  • sort: 布尔值,默认False,是否按键值排序
  • suffixes: 2-length sequence,公共字段别名
  • copy: 布尔值,默认True
  • indicator: 布尔或者字符串
  • validate: 字符串,默认None,检验merge是否为以下形式:”one_to_one”,”one_to_many”,”many_to_one”,”many_to_many”

concat

1
pandas.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)

按某一维度拼接pandas对象

参数:

  • objs:
  • axis: {0,1},默认为0
  • join: {‘inner’,’outer’},默认为outer,这个参数的意思是如果按行连接,列的处理方式,inner则只保留公共列,outer则列出所有列
  • join_axes:
  • ignore_index: 布尔值,默认为False,
  • key: sequence,默认None
1
2
3
4
import pandas as pd
df1 = pd.DataFrame([['a', 1], ['b', 2]],columns=['letter', 'number'])
df3 = pd.DataFrame([['c', 3, 'cat'], ['d', 4, 'dog']], columns=['letter', 'number', 'animal'])
pd.concat([df1, df3], join="inner")
1
2
3
4
5
letter	number
0 a 1
1 b 2
0 c 3
1 d 4
1
2
pd.concat([df1, df3], join="outer",ignore_index=True)
animal letter number
1
2
3
4
0	NaN	a	1
1 NaN b 2
2 cat c 3
3 dog d 4

总结

merge与join相比,join可以一次进行多个dataframe的连接,而merge一次只能进行两个dataframe, 但merge在连接字段的设置上更灵活,而concat只是进行dataframe的行或列的拼接。