,这一期我想和你们分享的是pandas中最多见的几种方法,这些方法某种程度上能够很好的替代Excel,这篇文章是pandas之旅的第三篇,主要会从如下几个方面和你们分享个人心得体会:python
话很少说,让咱们开始今天的Pandas之旅吧!git
首先merge的操做很是相似sql里面的join,实现将两个Dataframe根据一些共有的列链接起来,固然,在实际场景中,这些共有列通常是Id, 链接方式也丰富多样,能够选择inner(默认),left,right,outer 这几种模式,分别对应的是内链接,左链接,右链接github
首先让咱们简单的建立两个DF,分别为DataFrame1,DataFrame2,他们的公有列是keysql
import numpy as np
import pandas as pd
from pandas import Series, DataFrame
复制代码
# Let's make a dframe
dframe1 = DataFrame({'key':['X','Z','Y','Z','X','X'],'value_df1': np.arange(6)})
dframe1
复制代码
key | value_df1 | |
---|---|---|
0 | X | 0 |
1 | Z | 1 |
2 | Y | 2 |
3 | Z | 3 |
4 | X | 4 |
5 | X | 5 |
#Now lets make another dframe
dframe2 = DataFrame({'key':['Q','Y','Z'],'value_df2':[1,2,3]})
dframe2
复制代码
key | value_df2 | |
---|---|---|
0 | Q | 1 |
1 | Y | 2 |
2 | Z | 3 |
咱们如今能够简单地使用pd.merge(dframe1,dframe2)来实现Merge功能dom
pd.merge(dframe1,dframe2)
复制代码
key | value_df1 | value_df2 | |
---|---|---|---|
0 | Z | 1 | 3 |
1 | Z | 3 | 3 |
2 | Y | 2 | 2 |
咱们如今须要注意一点,X仅仅是存在于dframe1的key,在dframe2中不存在,所以你们能够发现,当咱们调用pd.merge的时候,会自动默认为inner join, 咱们再换一种方式写一下,你们就明白了:函数
pd.merge(dframe1,dframe2,on='key',how='inner')
复制代码
key | value_df1 | value_df2 | |
---|---|---|---|
0 | Z | 1 | 3 |
1 | Z | 3 | 3 |
2 | Y | 2 | 2 |
你们能够发现结果是同样的,看到这里,对sql熟悉的朋友们已经有感受了估计,由于实在是太像了,若是咱们不经过on和how来指定
想要merge的公有列或者方式,那么pd.merge就会自动寻找到两个DataFrame的相同列并自动默认为inner join,至此,
估计你们也能够猜出其余几种模式的merge啦
复制代码
如今一样的,让咱们看一下how='left'的状况,这是一个左链接
复制代码
pd.merge(dframe1,dframe2,on='key',how='left')
复制代码
key | value_df1 | value_df2 | |
---|---|---|---|
0 | X | 0 | NaN |
1 | Z | 1 | 3.0 |
2 | Y | 2 | 2.0 |
3 | Z | 3 | 3.0 |
4 | X | 4 | NaN |
5 | X | 5 | NaN |
咱们能够看到返回的是dframe1的全部key值对应的结果,若是在dframe2中不存在,显示为Nan空值学习
右链接的原理和左链接正相反spa
pd.merge(dframe1,dframe2,on='key',how='right')
复制代码
key | value_df1 | value_df2 | |
---|---|---|---|
0 | Z | 1.0 | 3 |
1 | Z | 3.0 | 3 |
2 | Y | 2.0 | 2 |
3 | Q | NaN | 1 |
这里Q只存在于drame2的key中code
#Choosing the "outer" method selects the union of both keys
pd.merge(dframe1,dframe2,on='key',how='outer')
复制代码
key | value_df1 | value_df2 | |
---|---|---|---|
0 | X | 0.0 | NaN |
1 | X | 4.0 | NaN |
2 | X | 5.0 | NaN |
3 | Z | 1.0 | 3.0 |
4 | Z | 3.0 | 3.0 |
5 | Y | 2.0 | 2.0 |
6 | Q | NaN | 1.0 |
这里就是一个并集的形式啦,其实就是一个union的结果,会把key这一列在两个Dataframe出现的全部值所有显示出来,若是有空值显示为Nan
复制代码
刚才咱们都是仅仅实现的在一个key上的merge,固然咱们也能够实现基于多个keys的merge排序
# Dframe on left
df_left = DataFrame({'key1': ['SF', 'SF', 'LA'],
'key2': ['one', 'two', 'one'],
'left_data': [10,20,30]})
df_left
复制代码
key1 | key2 | left_data | |
---|---|---|---|
0 | SF | one | 10 |
1 | SF | two | 20 |
2 | LA | one | 30 |
#Dframe on right
df_right = DataFrame({'key1': ['SF', 'SF', 'LA', 'LA'],
'key2': ['one', 'one', 'one', 'two'],
'right_data': [40,50,60,70]})
df_right
复制代码
key1 | key2 | right_data | |
---|---|---|---|
0 | SF | one | 40 |
1 | SF | one | 50 |
2 | LA | one | 60 |
3 | LA | two | 70 |
这是内链接(交集)的结果
复制代码
#Merge, Inner
pd.merge(df_left, df_right, on=['key1', 'key2'])
复制代码
key1 | key2 | left_data | right_data | |
---|---|---|---|---|
0 | SF | one | 10 | 40 |
1 | SF | one | 10 | 50 |
2 | LA | one | 30 | 60 |
这是外链接(并集)的结果
复制代码
#Merge, Outer
pd.merge(df_left, df_right, on=['key1', 'key2'],how='outer')
复制代码
key1 | key2 | left_data | right_data | |
---|---|---|---|---|
0 | SF | one | 10.0 | 40.0 |
1 | SF | one | 10.0 | 50.0 |
2 | SF | two | 20.0 | NaN |
3 | LA | one | 30.0 | 60.0 |
4 | LA | two | NaN | 70.0 |
这里还有一个地方很是有意思,你们能够发现如今df_left,df_right做为key的两列分别是key1和key2,它们的名字是相同的,刚刚咱们是经过制定on=['key1', 'key2'],那若是咱们只指定一列会怎么样呢?
pd.merge(df_left,df_right,on='key1')
复制代码
key1 | key2_x | left_data | key2_y | right_data | |
---|---|---|---|---|---|
0 | SF | one | 10 | one | 40 |
1 | SF | one | 10 | one | 50 |
2 | SF | two | 20 | one | 40 |
3 | SF | two | 20 | one | 50 |
4 | LA | one | 30 | one | 60 |
5 | LA | one | 30 | two | 70 |
你们能够看到pandas自动把key2这一列拆分红了key2_x和key2_y,都会显示在最后的merge结果里,若是咱们想要给这两列从新命名,也是很容易的:
# We can also specify what the suffix becomes
pd.merge(df_left,df_right, on='key1',suffixes=('_lefty','_righty'))
复制代码
key1 | key2_lefty | left_data | key2_righty | right_data | |
---|---|---|---|---|---|
0 | SF | one | 10 | one | 40 |
1 | SF | one | 10 | one | 50 |
2 | SF | two | 20 | one | 40 |
3 | SF | two | 20 | one | 50 |
4 | LA | one | 30 | one | 60 |
5 | LA | one | 30 | two | 70 |
像这样,咱们能够经过suffixes参数来指定拆分的列的名字。
咱们还能够实现几个Dataframe基于Index的merge,仍是老样子,先让咱们建立两个Dataframe
复制代码
df_left = DataFrame({'key': ['X','Y','Z','X','Y'],
'data': range(5)})
df_right = DataFrame({'group_data': [10, 20]}, index=['X', 'Y'])
复制代码
df_left
复制代码
key | data | |
---|---|---|
0 | X | 0 |
1 | Y | 1 |
2 | Z | 2 |
3 | X | 3 |
4 | Y | 4 |
df_right
复制代码
group_data | |
---|---|
X | 10 |
Y | 20 |
好了,如今咱们想要实现两个Dataframe的merge,可是条件是经过df_left的Key和df_right的Index
pd.merge(df_left,df_right,left_on='key',right_index=True)
复制代码
key | data | group_data | |
---|---|---|---|
0 | X | 0 | 10 |
3 | X | 3 | 10 |
1 | Y | 1 | 20 |
4 | Y | 4 | 20 |
这样咱们也能够获得结果。
# We can also get a union by using outer
pd.merge(df_left,df_right,left_on='key',right_index=True,how='outer')
复制代码
key | data | group_data | |
---|---|---|---|
0 | X | 0 | 10.0 |
3 | X | 3 | 10.0 |
1 | Y | 1 | 20.0 |
4 | Y | 4 | 20.0 |
2 | Z | 2 | NaN |
其余的merge方式就相似啦,这里就不一一说了,只是举一个outer join的例子
# 经过outer实现外链接,union并集
pd.merge(df_left,df_right,left_on='key',right_index=True,how='outer')
复制代码
key | data | group_data | |
---|---|---|---|
0 | X | 0 | 10.0 |
3 | X | 3 | 10.0 |
1 | Y | 1 | 20.0 |
4 | Y | 4 | 20.0 |
2 | Z | 2 | NaN |
咱们也能够尝试一些有意思的merge,好比,若是一个dataframe的index是多层嵌套的状况:
复制代码
df_left_hr = DataFrame({'key1': ['SF','SF','SF','LA','LA'],
'key2': [10, 20, 30, 20, 30],
'data_set': np.arange(5.)})
df_right_hr = DataFrame(np.arange(10).reshape((5, 2)),
index=[['LA','LA','SF','SF','SF'],
[20, 10, 10, 10, 20]],
columns=['col_1', 'col_2'])
复制代码
df_left_hr
复制代码
key1 | key2 | data_set | |
---|---|---|---|
0 | SF | 10 | 0.0 |
1 | SF | 20 | 1.0 |
2 | SF | 30 | 2.0 |
3 | LA | 20 | 3.0 |
4 | LA | 30 | 4.0 |
df_right_hr
复制代码
col_1 | col_2 | ||
---|---|---|---|
LA | 20 | 0 | 1 |
10 | 2 | 3 | |
SF | 10 | 4 | 5 |
10 | 6 | 7 | |
20 | 8 | 9 |
如今咱们穿建了两个Dataframe 分别是df_left_hr和df_right_hr(Index两层),若是咱们想经过使用df_left_hr的key1,key2 及df_right_hr的Index做为merge 的列,也是没有问题的
# Now we can merge the left by using keys and the right by its index
pd.merge(df_left_hr,df_right_hr,left_on=['key1','key2'],right_index=True)
复制代码
key1 | key2 | data_set | col_1 | col_2 | |
---|---|---|---|---|---|
0 | SF | 10 | 0.0 | 4 | 5 |
0 | SF | 10 | 0.0 | 6 | 7 |
1 | SF | 20 | 1.0 | 8 | 9 |
3 | LA | 20 | 3.0 | 0 | 1 |
基本到这里,我已经和你们分享了基础的Merge有关的全部操做,若是你平时生活工做中常用Excel执行相似操做的话,能够学习一下Merge哈,它会大幅度 减轻你的工做强度的!
如今咱们能够接着来看join相关的操做,先让咱们看一个小例子
left = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],
'B': ['B0', 'B1', 'B2', 'B3']},
index = ['K0', 'K1', 'K2', 'K3'])
right = pd.DataFrame({'C': ['C0', 'C1', 'C2', 'C3'],
'D': ['D0', 'D1', 'D2', 'D3']},
index = ['K0', 'K1', 'K2', 'K3'])
复制代码
left
复制代码
A | B | |
---|---|---|
K0 | A0 | B0 |
K1 | A1 | B1 |
K2 | A2 | B2 |
K3 | A3 | B3 |
right
复制代码
C | D | |
---|---|---|
K0 | C0 | D0 |
K1 | C1 | D1 |
K2 | C2 | D2 |
K3 | C3 | D3 |
left.join(right)
复制代码
A | B | C | D | |
---|---|---|---|---|
K0 | A0 | B0 | C0 | D0 |
K1 | A1 | B1 | C1 | D1 |
K2 | A2 | B2 | C2 | D2 |
K3 | A3 | B3 | C3 | D3 |
其实经过这一个小例子你们也就明白了,join无非就是合并,默认是横向,还有一个点须要注意的是,咱们其实能够经过join实现和merge同样的效果,可是为了 避免混淆,我不会多举其余的例子了,由于我我的认为通常状况下仍是用merge函数好一些
为了更加全面完全地了解Concat函数,你们能够先从一维的Numpy Array开始,首先让咱们简单的建立一个矩阵:
# Create a matrix
arr1 = np.arange(9).reshape((3,3))
arr1
复制代码
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
复制代码
接着让咱们经过concatenate函数进行横向拼接:
复制代码
np.concatenate([arr1,arr1],axis=1)
复制代码
array([[0, 1, 2, 0, 1, 2],
[3, 4, 5, 3, 4, 5],
[6, 7, 8, 6, 7, 8]])
复制代码
再让咱们进行纵向拼接:
# Let's see other axis options
np.concatenate([arr1,arr1],axis=0)
复制代码
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
复制代码
有了基础的印象以后,如今让咱们看看在pandas中是如何操做的:
# Lets create two Series with no overlap
ser1 = Series([0,1,2],index=['T','U','V'])
ser2 = Series([3,4],index=['X','Y'])
#Now let use concat (default is axis=0)
pd.concat([ser1,ser2])
复制代码
T 0
U 1
V 2
X 3
Y 4
dtype: int64
复制代码
在上面的例子中,咱们分别建立了两个没有重复Index的Series,而后用concat默认的把它们合并在一块儿,这时生成的依然是Series类型,若是咱们把axis换成1,那生成的就是Dataframe,像下面同样
pd.concat([ser1,ser2],axis=1,sort =True) # sort=Ture是默认的,pandas老是默认index排序
复制代码
0 | 1 | |
---|---|---|
T | 0.0 | NaN |
U | 1.0 | NaN |
V | 2.0 | NaN |
X | NaN | 3.0 |
Y | NaN | 4.0 |
咱们还能够指定在哪些index上进行concat:
pd.concat([ser1,ser2],axis=1,join_axes=[['U','V','Y']])
复制代码
0 | 1 | |
---|---|---|
U | 1.0 | NaN |
V | 2.0 | NaN |
Y | NaN | 4.0 |
也能够给不一样组的index加一层标签
pd.concat([ser1,ser2],keys=['cat1','cat2'])
复制代码
cat1 T 0
U 1
V 2
cat2 X 3
Y 4
dtype: int64
复制代码
若是把axis换成是1,那么keys就会变成column的名字:
pd.concat([ser1,ser2],axis=1,keys=['cat1','cat2'],sort=True)
复制代码
cat1 | cat2 | |
---|---|---|
T | 0.0 | NaN |
U | 1.0 | NaN |
V | 2.0 | NaN |
X | NaN | 3.0 |
Y | NaN | 4.0 |
若是是两个现成的dataframe直接进行concat也是同样:
dframe1 = DataFrame(np.random.randn(4,3), columns=['X', 'Y', 'Z'])
dframe2 = DataFrame(np.random.randn(3, 3), columns=['Y', 'Q', 'X'])
复制代码
dframe1
复制代码
X | Y | Z | |
---|---|---|---|
0 | 1.119976 | -0.853960 | 0.027451 |
1 | -0.536831 | 0.982092 | -0.157650 |
2 | -0.219322 | -1.489809 | 1.607735 |
3 | 0.767249 | -1.661912 | 0.038837 |
dframe2
复制代码
Y | Q | X | |
---|---|---|---|
0 | -0.035560 | 0.875282 | -1.630508 |
1 | -0.439484 | 0.096247 | 1.335693 |
2 | 0.746299 | 0.568684 | 1.197015 |
#若是没有对应的值,默认为NaN, 空值
pd.concat([dframe1,dframe2],sort=True)
复制代码
Q | X | Y | Z | |
---|---|---|---|---|
0 | NaN | 1.119976 | -0.853960 | 0.027451 |
1 | NaN | -0.536831 | 0.982092 | -0.157650 |
2 | NaN | -0.219322 | -1.489809 | 1.607735 |
3 | NaN | 0.767249 | -1.661912 | 0.038837 |
0 | 0.875282 | -1.630508 | -0.035560 | NaN |
1 | 0.096247 | 1.335693 | -0.439484 | NaN |
2 | 0.568684 | 1.197015 | 0.746299 | NaN |
今天我为你们主要总结了pandas中很是常见的三种方法:
你们能够根据本身的实际须要来决定使用哪种
我把这一期的ipynb文件和py文件放到了Github上,你们若是想要下载能够点击下面的连接:
这一期就到这里啦,但愿你们可以继续支持我,完结,撒花