通常我们用sql处理数据库里的数据,其实sql对数据的操作,在pandas中完全可以实现。
接下来,让我们根据sql执行顺序,来依次看看pandas对应的方法。
1. from … join 连表查询
sql中首先是从from table_name开始,单张表就不特地说了,若是多张表连接的时候,有5中连接情况。
table1 (inner) join table2
table1 left (outer) join table2
table1 right (outer) join table2
table1 full (outer) join table2
table1 cross join table2 # 笛卡尔积
在pandas中,有对应的函数能实现将表连接起来这个功能。
- merge
left: 左表表名
right :右表表名
how:连接方式,就有inner,left,right,outer,cross就对应sql中的各个连接方式
on,left_on,right_on,left_index,right_index:表示两张表需要根据什么值连接就可以写在这边。若两边相连的值具有相同的列名就直接用on,若是列名不同则分别用left_on和right_on分别指定列名,若是需要根据index相连,则通过left_index或者right_index=True指定。
suffixes:若是两张表中都有相同列名的字段,他默认是给你用column_x,column_y的方式给你区分开,可以自己定义列名
indicator:默认False,若是True,则会添加一列"_merge",这一列会标注合并键数据的存在是因为存在在左表(left_only),存在在右表(right_only)还是这个数据两个表都有(both)。
validate:可以验证合并是否为指定类型:有one_to_one(1:1),one_to_many(1:m),many_to_one(m:1),many_to_many(m:m),若是数据和选择的指定类型不符合,会直接报错。*
举个例子一起看看:
df1 = pd.DataFrame({'lkey': ['foo', 'bar', 'baz', 'foo','lll'],
'value': [1, 2, 3, 5,7]})
df2 = pd.DataFrame({'rkey': ['foo', 'bar', 'baz', 'foo','rrr'],
'value': [5, 6, 7, 8,6]})
# how默认是inner,若是inner连接可以默认不写
pd.merge(df1,df2,left_on='lkey',right_on='rkey');
# how=left,则左表中所有的数据都会显示
pd.merge(df1,df2,how='left',left_on='lkey',right_on='rkey')
# how=right右表的数据完全显示,并且修改重叠列名的后缀
pd.merge(df1,df2,how='right',left_on='lkey',right_on='rkey',suffixes=('_left','_right'))
pd.merge(df1,df2,how='outer',left_on='lkey',right_on='rkey',suffixes=('_left','_right'),indicator=True)
- join
DataFrame.join(other, on=None, how=‘left’, lsuffix=‘’, rsuffix=‘’, sort=False, validate=None)
和merge功能相同,可以连接表。但是这两个函数也有区别。
join默认的连接方式是左连接(left),而merge默认的连接方式是内连接(inner)。
join默认连接两张表的方式是根据两张表的index连接,若是要根据某一列连接,则要通过on指定,这个后面例子会给出。而merge则没有这个默认要求。
join时,如果两张表中有相同的列名,一定要指定lsuffix和rsuffix,否则会直接报错,而merge则没要求,默认会给你的相同列添加上_x,_y来区别来自两个不同的表的数据。
举个例子一起看看,还是那上面的那个数据,用join连接:
df1 = pd.DataFrame({'lkey': ['foo', 'bar', 'baz', 'foo','lll'],
'value': [1, 2, 3, 5,7]})
df2 = pd.DataFrame({'rkey': ['foo', 'bar', 'baz', 'foo','rrr'],
'value': [5, 6, 7, 8,6]})
df1.join(df2.set_index('rkey'),on='lkey',lsuffix='_l',rsuffix='_r')
# 因为重设了index,符合index_to_index连接,所以不需要在指定on
df1.set_index('lkey').join(df2.set_index('rkey'),lsuffix='_l',rsuffix='_r')
注意:join默认用的是df1和df2的index去连接。若是需要用某一列去连接,可以用on指定在左表中的列名,但是此时还是用右表中的index去连接,如果on指定左表的多列,那右表必须是符合索引。
df1和df2都是value列,所以必须指定lsuffix和rsuffix,否则直接报错,你可以看看。
# 若是需要根据某两列去匹配表
df1 = pd.DataFrame({'lkey': ['foo', 'bar', 'baz', 'foo','lll'],
'lcol':['aa','bb','aa','bb','aa'],
'value': [1, 2, 3, 5,7]})
df2 = pd.DataFrame({'rkey': ['foo', 'bar', 'baz', 'foo','rrr'],
'rcol':['aa','bb','aa','aa','aa'],
'value': [5, 6, 7, 8,6]})
df1.join(df2.set_index(['rkey','rcol']),on=['lkey','lcol'],how='outer',lsuffix='_l',rsuffix='_r')
# 当两个表用复合索引连接时,还是必须用on指定索引名
df1.set_index(['lkey','lcol']).join(df2.set_index(['rkey','rcol']),on=['lkey','lcol'],how='outer',lsuffix='_l',rsuffix='_r')
如此看来,其实join用起来不如merge方便,不需要查看两张表的index是否是连接的键。并且merge对于两个表中相同的列名会自动添加_x,_y帮助识别,而不是直接报错,必须手动指定。
但是join有一个优点的。他可以同时合并多个dataframe。
df1 = pd.DataFrame({'lkey': ['foo', 'bar', 'baz', 'foo','lll'],
'value': [1, 2, 3, 5,7]})
df2 = pd.DataFrame({'rkey': ['foo', 'bar', 'baz', 'foo','rrr'],
'value': [5, 6, 7, 8,6]})
df3 = pd.DataFrame({'rkey': ['foo', 'bar', 'baz', 'foo','lll','rrr'],
'value': [7,6,3,5,8,5]})
df1.set_index('lkey').join([df2.set_index('rkey'),df3.set_index('rkey')])
# 当合并多个dataframe的时候,此时已经没必要指定lsuffix,rsuffix,哪怕指定也无效
df1.set_index('lkey').join([df2.set_index('rkey'),df3.set_index('rkey')],how='outer',lsuffix='_l',rsuffix='_r')
# 当同时合并多个dataframe时,只支持行索引连接,不能使用参数on。使用on会报错
df1.join([df2.set_index('rkey'),df3.set_index('rkey')],on='lkey')