pandas小结(六)merge数据合并

2017年1月15日 发表评论 阅读评论

在《pandas小结(五)concat数据合并》中提到了数据合并,本篇学习另一个数据合并方法merge,不过这个和concat是有区别的,concat方法准确的说更像是级联,而不算合并,merge才是真正意义的合并。merge个人用的比较多的一个场景就是两个pandas数据,有相同的列数据,需要根据相同的列数据进行合并的。

一、merage函数介绍

merage函数的用法如下:

pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None,
left_index=False, right_index=False, sort=True)

其中的参数用法为:

  • left - 一个DataFrame对象。
  • right - 另一个DataFrame对象。
  • on - 列(名称)连接,必须在左和右DataFrame对象中存在(找到)。
  • left_on - 左侧DataFrame中的列用作键,可以是列名或长度等于DataFrame长度的数组。
  • right_on - 来自右的DataFrame的列作为键,可以是列名或长度等于DataFrame长度的数组。
  • left_index - 如果为True,则使用左侧DataFrame中的索引(行标签)作为其连接键。 在具有MultiIndex(分层)的DataFrame的情况下,级别的数量必须与来自右DataFrame的连接键的数量相匹配。
  • right_index - 与右DataFrame的left_index具有相同的用法。
  • how - inner(内连接),left(左外连接),right(右外连接),outer(全外连接);默认为inner。
  • sort - 按照字典顺序通过连接键对结果DataFrame进行排序。默认为True,设置为False时,在很多情况下大大提高性能。

上面提到的how连接方式,为了便于理解,我们使用SQL语句和pands语句进行下比对。

1、内连接

符合连接条件和查询条件的数据行,相当于数据库中的jion,SQL语句表示如下:

SELECT * FROM df1 INNER JOIN df2 ON df1.key = df2.key;
或
SELECT * FROM df1,df2 where df1.key=df2.key;
# 对应的pandas语句如下:
pd.merge(df1, df2, on='key')

2、左外连接

符合连接条件和查询条件的数据行并返回左表中不符合连接条件但符合查询条件的数据行,相当于数据库中的left outer join,示例SQL语句 :

-- show all records from df1
SELECT * FROM df1 LEFT OUTER JOIN df2  ON df1.key = df2.key;
# 对应pandas语句:
pd.merge(df1, df2, on='key', how='left')

3、右外连接

符合连接条件和查询条件的数据行并返回右表中不符合连接条件单符合查询条件的数据行,相当于数据库中的right outer join,示例SQL语句:

-- show all records from df2
SELECT * FROM df1 RIGHT OUTER JOIN df2  ON df1.key = df2.key;
# 对应pandas语句:
pd.merge(df1, df2, on='key', how='right')

4、全外连接

符合连接条件和查询条件的数据行并返回左表和左表中不符合连接条件单符合查询条件的数据行。全外连接相当于左外连接与左外连接的合集(去掉重复),相当于数据库中的full outer join,示例SQL语句:

-- show all records from both tables
SELECT * FROM df1 FULL OUTER JOIN df2  ON df1.key = df2.key;
# 对应pandas语句
pd.merge(df1, df2, on='key', how='outer')

对应图如下:

pandas-merage

二、数据合并示例

回到最初的话,这里我给出两个数据,其中有一列的值是唯一,且可以根据该值进行合并的,我们先成后一个测试数据,生成pandas测试数据的方法有如下两种:

df=DataFrame(columns=['code','prce'])
df.loc[0]=['002541','40']
df.loc[1]=['002528','35']
或
df = pd.DataFrame([[1, 2], [3, 4]], columns=['code','prce'])

添加数据,也可以append,也可以使用字典的方式进行,如下:

>>> res = pd.DataFrame(columns=('lib', 'qty1', 'qty2'))
>>> res = res.append([{'qty1':10.0}], ignore_index=True)
>>> print(res.head())
# 输出
   lib  qty1  qty2
0  NaN  10.0   NaN

完整的示例代码如下:

import pandas as pd
from pandas import DataFrame
df=DataFrame(columns=['code','age'])
df.loc[10]=['002541','40']
df.loc[11]=['002528','35']
print(df)
print("---------------------------------")
df2 = pd.DataFrame([['002541','小黄狗','100'],['002560','猫咪','60'], ['002528','大飞','80']] , columns=['code','name','price'])
print(df2)
print("---------------------------------")
result = pd.merge(df,df2,left_on='code',right_on='code')
print(result)
# 执行结果如下:
# python merage.py
      code age
10  002541  40
11  002528  35
---------------------------------
     code name price
0  002541  小黄狗   100
1  002560   猫咪    60
2  002528   大飞    80
---------------------------------
     code age name price
0  002541  40  小黄狗   100
1  002528  35   大飞    80

从上面的输出可以看到,这里默认使用的是内连接,虽然两者之间的index不一值,但通过指定code作为两者连接的依据,两边的值还是匹配在了一起,而且是以第一个df中的数据列为基准。这里因为两边的列名称相同,实际上是可以直接简单为on进行内连接的,其简写类似如下示例:

import pandas as pd
left = pd.DataFrame({
         'id':[1,2,3,4,5],
         'Name': ['Alex', 'Amy', 'Allen', 'Alice', 'Ayoung'],
         'subject_id':['sub1','sub2','sub4','sub6','sub5']})
right = pd.DataFrame(
         {'id':[1,2,3,4,5],
         'Name': ['Billy', 'Brian', 'Bran', 'Bryce', 'Betty'],
         'subject_id':['sub2','sub4','sub3','sub6','sub5']})
rs = pd.merge(left,right,on='id')
print(rs)

当然我们也可以进行更严格的要求,要求两列的值都相同的才进行匹配输出:

import pandas as pd
left = pd.DataFrame({
         'id':[1,2,3,4,5],
         'Name': ['Alex', 'Amy', 'Allen', 'Alice', 'Ayoung'],
         'subject_id':['sub1','sub2','sub4','sub6','sub5']})
right = pd.DataFrame(
         {'id':[1,2,3,4,5],
         'Name': ['Billy', 'Brian', 'Bran', 'Bryce', 'Betty'],
         'subject_id':['sub2','sub4','sub3','sub6','sub5']})
rs = pd.merge(left,right,on=['id','subject_id'])
print(rs)

该示例的输出就只有两行数据,显然是取的两者的交集。

显然我们还可以加上how值,同时可以尝试修改how值,查看具体的输出结果:

import pandas as pd
left = pd.DataFrame({
         'id':[1,2,3,4,5],
         'Name': ['Alex', 'Amy', 'Allen', 'Alice', 'Ayoung'],
         'subject_id':['sub1','sub2','sub4','sub6','sub5']})
right = pd.DataFrame(
         {'id':[1,2,3,4,5],
         'Name': ['Billy', 'Brian', 'Bran', 'Bryce', 'Betty'],
         'subject_id':['sub2','sub4','sub3','sub6','sub5']})
rs = pd.merge(left, right, on='subject_id', how='left')
print (rs)

参考页面:pandas官方merge用法页




本站的发展离不开您的资助,金额随意,欢迎来赏!

You can donate through PayPal.
My paypal id: itybku@139.com
Paypal page: https://www.paypal.me/361way