小蛇学python(15)pandas之数据合并
在python的pandas中,合并数据共有三种思路。
其一,关系型数据库模式的连接操作。
其二,沿轴将多个操作对象拼接在一起。
其三,对互有重复数据的处理与合并。
我们分别来进行介绍。
1. merge、join
先从一个简单的例子开始。
import pandas as pd
from pandas import DataFrame
df1 = DataFrame({'key' : ['b', 'b', 'a', 'c', 'a', 'a', 'b'],
'data1' : range(7)})
df2 = DataFrame({'key' : ['a', 'b', 'd'],
'data2' : range(3)})
df = pd.merge(df1, df2)
print(df1)
print(df2)
print(df)
image.png
这里,并没有指定要用哪个列进行连接,如果没有指定,就会默认将重叠列的列名当作连接键。这里连接的结果是按照笛卡儿积的逻辑实现的。在这个例子中表现不太明显,我们再看下一个例子。
import pandas as pd
from pandas import DataFrame
df1 = DataFrame({'key' : ['b', 'b', 'a', 'c', 'a', 'b'],
'data1' : range(6)})
df2 = DataFrame({'key' : ['a', 'b', 'a', 'b', 'd'],
'data2' : range(5)})
df = pd.merge(df1, df2, on='key', how='left')
print(df1)
print(df2)
print(df)
image.png
我们看到,表格1里有3个b,表格2里有2个b,所以最终合并的表格里就有6个b,这就是所谓的笛卡尔乘积。在这里我也用了参数on,它的作用就是指定两个表格按照哪一列合并。我也用了参数how,它所决定的是合并方式。一共有四种方式分别为inner、left、right、outer,分别代表取交集,取交集加上左边表格剩余部分,取交集加右边表格剩余部分,取并集。
其实,如果两个对象的列名不同,但是列里的内容相同,也是可以合并的。看下面这个例子。
import pandas as pd
from pandas import DataFrame
df1 = DataFrame({'lkey' : ['b', 'b', 'a', 'c', 'a', 'b'],
'data1' : range(6)})
df2 = DataFrame({'rkey' : ['a', 'b','d'],
'data2' : range(3)})
df = pd.merge(df1, df2, left_on='lkey', right_on='rkey')
print(df1)
print(df2)
print(df)
image.png
如果要根据多个键进行合并,传入一个由列名组成的列表即可。你可以这样理解,多个键形成一系列元组,并将其充当单个连接键。看下面这个例子。
import pandas as pd
from pandas import DataFrame
df1 = DataFrame({'key1' : ['foo', 'foo', 'bar'],
'key2' : ['one', 'two', 'one'],
'lval' : [1, 2, 3]})
df2 = DataFrame({'key1' : ['foo', 'foo', 'bar', 'bar'],
'key2' : ['one', 'one', 'one', 'two'],
'rval' : [4, 5, 6 ,7]})
df = pd.merge(df1, df2, on=['key1', 'key2'], how='outer')
print(df1)
print(df2)
print(df)
image.png
有一种很常见的情况,就是表格中的连接键位于索引中。看下面这个例子如何解决。
import pandas as pd
from pandas import DataFrame
df1 = DataFrame({'key' : ['a', 'b', 'a', 'a', 'b', 'c'],
'value' : range(6)})
df2 = DataFrame({'group_val' : [3.5, 7]},
index=['a', 'b'])
df = pd.merge(df1, df2, left_on='key', right_index=True)
print(df1)
print(df2)
print(df)
image.png
DataFrame还有一个join实例方法,它能更为方便得实现按索引合并。它还可以用于合并多个带有相同或者相似索引的DataFrame对象。
这里就举一个例子,因为这个方法比较简单。
import numpy as np
import pandas as pd
from pandas import DataFrame
frame1 = DataFrame({'length' : [1, 2, 3, 4, 5],
'price' : [12.33, 11.44, 33.21, 13.23, 33.62]},
index=['ball', 'pencil', 'pen', 'mug', 'ashtray'])
frame2 = DataFrame({'local' : ['uk', 'pland', 'china', 'japan'],
'color' : ['while', 'red', 'red', 'black']},
index=['pencil', 'pencil', 'ball', 'pen'])
print(frame1)
print(frame2)
frame1.join(frame2)
print(frame1)
image.png
需要注意的是,只用join时,两个表格除了索引不得有重复的列。
2. contact
默认情况下,concat是在axis=0上工作的。所谓轴,即是要么横着拼接,要么竖着拼接的意思。
比如想把2017年和2018年吉林大学在安徽省的专业招收人数情况横向拼接起来,就会用到concat。如下例子。
import pandas as pd
jilindaxue2018 = pd.read_csv('jilindaxue2018.csv')
jilindaxue2018_major = jilindaxue2018.loc[:, '专业']
jilindaxue2018_anhui = jilindaxue2018.loc[:, '安徽']
jilindaxue2017 = pd.read_csv('jilindaxue2017.csv')
jilindaxue2017_anhui = jilindaxue2017.loc[:, '安徽']
frame = [jilindaxue2018_major, jilindaxue2018_anhui, jilindaxue2017_anhui]
data = pd.concat(frame, axis=1)
data.columns = ['专业', '安徽2018', '安徽2017']
print(data)
data.to_csv('data.csv', index=False, encoding='gbk')
3. 合并重叠数据
还有一种情况,就是用参数对象中的数据为调用者对象的缺失数据打补丁。这里,我们就需要用到combine_first函数。
import pandas as pd
from pandas import DataFrame
import numpy as np
df1 = DataFrame({'a' : [1, np.nan, 5, np.nan],
'b' : [np.nan, 2, np.nan, 6],
'c' : range(2, 18, 4)})
df2 = DataFrame({'a' : [5, 4, np.nan, 3, 7],
'b' : [np.nan, 3, 4, 6, 8],})
print(df1)
print(df2)
df1.combine_first(df2)
print(df1)
image.png