参考资料:活用pandas库
1、连接
(1)添加行
import pandas as pd
df1=pd.read_csv(r"C:\王池池\学习\python\活用pandas库\data\concat_1.csv")
df2=pd.read_csv(r"C:\王池池\学习\python\活用pandas库\data\concat_2.csv")
df3=pd.read_csv(r"C:\王池池\学习\python\活用pandas库\data\concat_3.csv")
print(df1)
print(df2)
print(df3)
可以使用pandas的concat函数把上面3个DataFrame连接起来。当把多个DataFrame传入concat函数时,要把它们放入同一列表中。
row_concat=pd.concat([df1,df2,df3])
print(row_concat)
通过查看row_concat的行名(比如行索引)会发现它们只是原始行索引的简单堆叠,我们可以用iloc和loc查看二者的区别:
下面尝试将一行数据添加到DataFrame中:
# 新建一行数据
new_row_series=pd.Series(['n1','n2','n3','n4'])
# 尝试向DataFrame添加新行
pd.concat([df1,new_row_series])
上面示例中显示,并未将一行Series成功追加到DataFrame中。我们需要把Series转换成DataFrame,该DataFrame包含一行数据,并使用columns参数指定数据需要绑定的列名。
# 请注意,这里使用了两个方括号
new_row_df=pd.DataFrame([['n1','n2','n3','n4']],columns=['A','B','C','D'])
print(new_row_df)
pd.concat([df1,new_row_df])
concat是通用函数,可以同时连接多个对象。如果只需要向现有DataFrame追加一个对象,完全可以使用append函数来实现。但目前已有警告:append会在将来的pandas版本中被删除,建议使用concat函数。
concat函数有一个ignore_index参数,使用此参数可以充值连接后的行索引。如下:
pd.concat([df1,df2,df3],ignore_index=True)
(2)添加列
连接列与连接行做法非常相似,主要区别在于concat函数中的轴参数axis。axis的默认值为0,表示按行连接数据。如果把axis=1传递给concat函数,它将按列连接数据。
pd.concat([df1,df2,df3],axis=1)
当阐释根据列名取数据子集时,效果如下:
col_concat=pd.concat([df1,df2,df3],axis=1)
col_concat['A']
可以直接向DataFrame添加一列,而无须使用任何pandas函数。而使用concat函数时,只要向他传递一个DataFrame,它就可以正常工作。但使用这种方法需要更多代码,如下:如下:
col_concat['new_col_list']=['n1','n2','n3','n4']
# 也可以写成
col_concat['new_col_list']=pd.Series(['n1','n2','n3','n4'])
col_concat
(3)不同索引下的连接操作
①连接具有不同列的行
# 调整原来的DataFrame的列索引
df1.columns=['A','B','C','D']
df2.columns=['E','F','G','H']
df3.columns=['A','C','F','H']
# 直接用concat函数进行连接
pd.concat([df1,df2,df3])
为了避免包含NaN值,可以只保留链接地对象共有的列。可以用concat函数join参数实现。默认情况下,joint的值为outer,即保留所有列。
pd.concat([df1,df3],ignore_index=False,join='inner')
②连接具有不同行的列
# 改变原来3个DataFrame的行索引
df1.index=[0,1,2,3]
df2.index=[4,5,6,7]
df3.index=[0,2,5,7]
pd.concat([df1,df2,df3],axis=1)
这里添加join参数,将其设为‘inner’,结果将只保留共有行索引的结果。
pd.concat([df1,df3],axis=1,join='inner')
2、合并多个数据集
在数据库中,合并数据表时会用到join="inner"和默认的join="outer"参数。pandas中也有类似的操作:pd.join命令会依据索引合并DataFrame对象,而merge命令更加灵活。如果想依据行索引来合并DataFrame,可以考虑使用join函数。
# 导入数据
person=pd.read_csv(r"...\data\survey_person.csv")
site=pd.read_csv(r"...\data\survey_site.csv")
survey=pd.read_csv(r"...\data\survey_survey.csv")
visited=pd.read_csv(r"...\data\survey_visited.csv")
(1)一对一合并
# merge函数的参数how默认值为inner
# 这里无须专门指定
visited_subset=visited.loc[[0,2,6],]
o2o_merge=site.merge(visited_subset,left_on='name',right_on='site')
o2o_merge
②多对一合并
site数据集中的name是有重复的,合并中会复制包含单个观测值对应的DataFrame。
o2o_merge=site.merge(visited,left_on='name',right_on='site')
o2o_merge
③多对多合并
有时需要基于多列进行数据匹配,比如有两个DataFrame,其中以个由person和survey合并而成,另一个由visited和survey合并而成。
ps=person.merge(survey,left_on='ident',right_on='person')
vs=visited.merge(survey,left_on='ident',right_on='taken')
print(ps.columns)
print(vs.columns)
ps_vs=ps.merge(vs,
left_on=['ident','taken','quant','reading'],
right_on=['person','ident','quant','reading'])
ps_vs.head()
如果列名存在冲突时,pandas会自动向列名添加后缀。上面的输出中,带有_x后缀的列值来自左边的DataFrame,带_y后缀的列值来自右边的DataFrame。