pandas的拼接分为两种:
- 级联:pd.concat, pd.append
- 合并:pd.merge, pd.join
import numpy as np
import pandas as pd
from pandas import Series,DataFrame
0. 回顾numpy的级联
练习12:
- 生成2个3*3的矩阵,对其分别进行两个维度上的级联
nd1 = np.random.randint(0,150,size = (6,3))
nd2 = np.random.randint(0,150,size = (2,3))
np.concatenate((nd1,nd2))
np.concatenate([nd1,nd2])
1. 使用pd.concat()级联
pandas使用pd.concat函数,与np.concatenate函数类似,只是多了一些参数:
pd.concat(objs, axis=0, join='outer', join_axes=None, ignore_index=False,
keys=None, levels=None, names=None, verify_integrity=False,
copy=True)
1) 简单级联
和np.concatenate一样,优先增加行数(默认axis=0)
df1 = DataFrame(np.random.randint(0,150,size = (4,3)),columns=['Python','Math','En'],index=list('abcd'))
df2 = DataFrame(np.random.randint(0,150,size = (5,3)),columns=['Python','Math','En'],index=list('efghi'))
display(df1,df2)
pd.concat([df1,df2])
- 可以通过设置axis来改变级联方向
pd.concat((df1,df3),axis = 1)
注意index在级联时可以重复
也可以选择忽略ignore_index,重新索引
df4 = pd.concat([df1,df3],ignore_index=True)
# df4 重新设置索引
df4.index = list('abcdefgh')
df4
或者使用多层索引 keys
concat([x,y],keys=['x','y'])
# 期中
df1 = DataFrame(np.random.randint(0,150,size = (4,3)),columns=['Python','Math','En'],index = list('ABCD'))
# 期末
df2 = DataFrame(np.random.randint(0,150,size = (4,3)),columns=['Python','Math','En'],index = list('ABCD'))
display(df1,df2)
df3 = pd.concat([df1,df2],keys = ['期中','期末'])
df3
df3.unstack(level=0).stack()
2) 不匹配级联
不匹配指的是级联的维度的索引不一致。例如纵向级联时列索引不一致,横向级联时行索引不一致
有3种连接方式:
- 外连接:补NaN(默认模式)
# outer 将所有的数据保存到新的DataFrame
pd.concat((df1,df4),join='outer')
- 内连接:只连接匹配的项
# inner 将共同的列,进行合并
pd.concat((df1,df4),join = 'inner')
- 连接指定轴 join_axes
df1.columns
output:
Index(['Python', 'Math', 'En'], dtype='object')
df4.columns
output:
Index(['Python', 'Math', 'Chinese'], dtype='object')
# axis
pd.concat((df1,df4),join_axes=[df1.columns])
# axis
pd.concat((df1,df4,df2),join_axes=[df4.columns])
3) 使用append()函数添加
由于在后面级联的使用非常普遍,因此有一个函数append专门用于在后面添加
# append 追加
df1.append(df2)
2. 使用pd.merge()合并
merge的参数
- on:列名,join用来对齐的那一列的名字,用到这个参数的时候一定要保证左表和右表用来对齐的那一列都有相同的列名。
- left_on:左表对齐的列,可以是列名,也可以是和dataframe同样长度的arrays。
- right_on:右表对齐的列,可以是列名,也可以是和dataframe同样长度的arrays。
- left_index/ right_index: 如果是True的haunted以index作为对齐的key
- how:数据融合的方法。
- sort:根据dataframe合并的keys按字典顺序排序,默认是,如果置false可以提高表现。
merge的默认合并方法:
merge用于表内部基于 index-on-index 和 index-on-column(s) 的合并,但默认是基于index来合并。
1.1 通过on指定数据合并对齐的列
result = pd.merge(left, right, on=['key1', 'key2'])
#left
#只保留左表的所有数据
result = pd.merge(left, right, how='left', on=['key1', 'key2'])
#right
#保留右表的所有数据
result = pd.merge(left, right, how='right', on=['key1', 'key2'])
#outer
#保留两个表的所有信息
result = pd.merge(left, right, how='outer', on=['key1', 'key2'])
#inner
#只保留两个表中公共部分的信息
result = pd.merge(left, right, how='inner', on=['key1', 'key2'])
1.3 join方法
dataframe内置的join方法是一种快速合并的方法。它默认以index作为对齐的列。
1.3.1 how 参数
join中的how参数和merge中的how参数一样,用来指定表合并保留数据的规则。
1.3.2 on 参数
在实际应用中如果右表的索引值正是左表的某一列的值,这时可以通过将 右表的索引 和 左表的列 对齐合并这样灵活的方式进行合并。
result = left.join(right, on='key')
1.3.3 suffix后缀参数
如果和表合并的过程中遇到有一列两个表都同名,但是值不同,合并的时候又都想保留下来,就可以用suffixes给每个表的重复列名增加后缀。
result = pd.merge(left, right, on='k', suffixes=['_l', '_r'])
1.4 组合多个dataframe
一次组合多个dataframe的时候可以传入元素为dataframe的列表或者tuple。一次join多个,一次解决多次烦恼~
result = left.join([right, right2])
merge与concat的区别在于,merge需要依据某一共同的行或列来进行合并
使用pd.merge()合并时,会自动根据两者相同column名称的那一列,作为key来进行合并。
注意每一列元素的顺序不要求一致
df_id = DataFrame({'id':[1,2,3,4]},index = list('ABCD'))
df_id
df2 = DataFrame(np.random.randint(0,150,size=(4,3) ),index=list('ABCD'),columns=['语文','政治','历史'])
df2 = pd.concat([df2,df_id],axis = 1)
df2
1) 一对一合并
# merge 默认情况下,列增加了
df1.merge(df2)
2) 多对一合并
3) 多对多合并
4) key的规范化
- 使用on=显式指定哪一列为key,当有多个key相同时使用
# 指明on根据那一列进行融合,不指名,根据根据所有的共同的列名进行融合
# 不指名的时候,语文和id都是共同列
df2.merge(df3,on = 'id',suffixes=('_期中','_期末') )
# df2 左边
# df4 右边
df2.merge(df4,left_on='id',right_on='Id')
- 使用left_on和right_on指定左右两边的列作为key,当左右两边的key都不想等时使用
df2.merge(df5,left_on='id',right_index=True)
5) 内合并与外合并
- 内合并:只保留两者都有的key(默认模式)
df2.merge(df3,left_on='id',right_on='Id',how = 'inner')
- 外合并 how='outer':补NaN
# 将两个DataFrame中所有的数据,都保留下来
df2.merge(df3,left_on='id',right_on='Id',how = 'outer')
- 左合并、右合并:how='left',how='right',
df2.merge(df3,left_on='id',right_on='Id',how = 'left')
df2.merge(df3,left_on='id',right_on='Id',how = 'right')
6) 列冲突的解决
当列冲突时,即有多个列名称相同时,需要使用on=来指定哪一个列作为key,配合suffixes指定冲突列名
可以使用suffixes=自己指定后缀