vlookup和数据透视是Excel商业数据分析中最重要的两个手段。上一章介绍的是数据透视,那么本章就介绍另外一个:vlookup,在数据库中SQL常用的join也是这种。同时也介绍一下与之相接近的级联功能。
一、匹配合并 实现Excel的vlookup功能或者说数据库的join功能,在pandas中通过merge函数来实现比较方便灵活,有很多的参数,我们介绍其中几个重要的。pd.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, validate=None)
示例如下:
import pandas as pdimport numpy as npdf1 = pd.DataFrame({'地区':['苏A','苏A','苏B','苏B','苏C','苏C'], '门店':['门店1','门店2','门店3','门店4','门店5','门店6'], '销售额':np.random.randint(60,100,size = 6), '员工人数':np.random.randint(5,10, size=6)})df2 = pd.DataFrame({'地区':['苏B','苏B','苏C','苏C','苏D','苏D'], '门店':['门店3','门店4','门店5','门店6','门店7','门店8'], '上月销售额':np.random.randint(60,100,size = 6), '员工人数':np.random.randint(5,10, size=6)})display(df1, df2)
1、on、left_on、right_on参数
left是拼接的左侧DataFrame对象,right是右侧DataFrame对象
on: 要加入的列或索引级别名称。必须在左侧和右侧DataFrame对象中找到。如果未传递且left_index和right_index为False,则DataFrame中的列的交集将被推断为连接键。
left_on:左侧DataFrame中的列或索引级别用作键。可以是列名,索引级名称,也可以是长度等于DataFrame长度的数组。同理,right_on是右侧的。
df1.merge(df2, on = '门店')
# 当两张表相链接的列名不一致时,需要分别写left_on和right_ondf1.merge(df2, left_on = '门店', right_on = '门店')
2、suffixes参数
如果两个DataFrame中有相同的列名,合并时默认会在第一个DataFrame的列名后加后缀_x, 在第二个的后面加_y。如果想修改需要用到参数suffixes=(,)。默认为(‘x’,’ y’)。
df1.merge(df2, left_on = '门店', right_on = '门店', suffixes= ('_本月', '_上月'))
3、how参数
how: 取值共有 ‘left’, ‘right’, ‘outer’, ‘inner’四个取值. 默认inner。inner是取交集,outer取并集。比如left:[‘A’,‘B’,‘C’];right[’'A,‘C’,‘D’];inner取交集的话,left中出现的A会和right中出现的一个A进行匹配拼接,如果没有是B,在right中没有匹配到,则会丢失。'outer’取并集,出现的A会进行一一匹配,没有同时出现的会将缺失的部分添加缺失值。
df1.merge(df2, on = ['地区', '门店'], how = 'outer', suffixes= ('_本月', '_上月'))
在使用how的时候就会产生空值。只需要使用fillna()就可以填充了。
df3 = df1.merge(df2, on = ['地区', '门店'], how = 'outer', suffixes= ('_本月', '_上月'))df3.fillna(999)
4、left_index、right_index参数
如果合并的时候要用索引作为键的话,就不能用on, left_on, right_on了,要使用left_index=True, right_index=True。
left_index: 如果为True,则使用左侧DataFrame中的索引(行标签)作为其连接键。对于具有MultiIndex(分层)的DataFrame,级别数必须与右侧DataFrame中的连接键数相匹配。right_index: 与left_index功能相似。
将两张表的‘门店’设为索引df4 = df1[['地区', '门店', '销售额']].set_index(keys = '门店')df5 = df2[['门店', '上月销售额']].set_index(keys = '门店')display(df4, df5)
此时两张表除了‘门店’这个索引之外,没有相同可做连接的列。因此,on、left_on、right_on都失灵了。这时候就需要使用left_index和right_index。
df4.merge(df5, how = 'inner', left_index = True, right_index = True)
5、indicator参数
indicator=True,这个参数会添加一列,用来注明,每一行是来自于哪个DataFrame
df1.merge(df2, on = ['地区', '门店'], how = 'left', indicator = True)
二、级联操作
pd.concat(objs,axis=0,join='outer',join_axes=None,ignore_index=False)
其中,
- objs - 这是Series,DataFrame或Panel对象的序列或映射。
- axis -
{0,1,...}
,默认为0
,这是连接的轴。 - join -
{'inner', 'outer'}
,默认inner
。如何处理其他轴上的索引。联合的外部和交叉的内部。 - ignore_index − 布尔值,默认为
False
。如果指定为True
,则不要使用连接轴上的索引值。结果轴将被标记为:0,...,n-1
。 - join_axes - 这是Index对象的列表。用于其他
(n-1)
轴的特定索引,而不是执行内部/外部集逻辑。
示例如下,还以之前的数据为例:
import pandas as pdimport numpy as npdf1 = pd.DataFrame({'地区':['苏A','苏A','苏B','苏B','苏C','苏C'], '门店':['门店1','门店2','门店3','门店4','门店5','门店6'], '销售额':np.random.randint(60,100,size = 6), '员工人数':np.random.randint(5,10, size=6)})df2 = pd.DataFrame({'地区':['苏B','苏B','苏C','苏C','苏D','苏D'], '门店':['门店3','门店4','门店5','门店6','门店7','门店8'], '销售额':np.random.randint(60,100,size = 6), '员工人数':np.random.randint(5,10, size=6)})display(df1, df2)
pd.concat([df1, df2])
如果把特定的键与每个DataFrame关联起来,需要通过使用键参数来实现
pd.concat([df1, df2], keys = ['本月', '上月'])
结果的索引是重复的; 每个索引重复。如果想要生成的对象必须遵循自己的索引,请将ignore_index
设置为True
pd.concat([df1, df2], ignore_index=True)
如果需要沿axis=1
添加两个对象,则会添加新列。
pd.concat([df1, df2], axis = 1)
除此之外,我们最开始使用的append用法,也都是可以使用的。