Python数据分析pandas之数据拼接与连接
Posted ShenLiang2025
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python数据分析pandas之数据拼接与连接相关的知识,希望对你有一定的参考价值。
Python数据分析pandas之数据拼接与连接
数据拼接处理
数据拼接处理指的是numpy、pandas里对数据的拼接、连接、合并等多种方法的概称。有时我们处理的数据会分很多步骤,而中间或者最终的结果可能是由多个数据框、多维数组通过拼接等方式组装而来。本章节主要介绍如何使用拼接、连接、合并的方法处理numpy和pandas类型的数据。
数据拼接
数据拼接主要是对行(列)名相同的元素进行拼接,行拼接则会使行变多,而列不变,而列拼接则是列变多,而行固定。
Numpy数组axis=0行拼接
# 1 通过np的concatenate方法对数组进行拼接,拼接时不会改变数组的维数。
x=[9,8,7]
y=[6,5,4]
z=[3,2,1]
data=np.concatenate([x,y,z],axis=0)
print(data)
#如果我们指定axis=1,则会报错,错误信息见下:
numpy.AxisError: axis 1 is out of bounds for array of dimension 1
# 2 拼接时如果指定的axis=0,则是行拼接,即行变多,而列保持不变;而axis=1,则是列拼接,即列变多,而行保持不变。这里不变是相对第一个数组。
arr1=np.array([[1,2,3],[4,5,3],[11,12,13]])
arr2=np.array([[6,7,8],[21,22,23]])
#这里行可以少于第一个数组,但列要相同。
print(np.concatenate([arr1,arr2],axis=0))
#结果
[[ 1 2 3]
[ 4 5 3]
[11 12 13]
[ 6 7 8]
[21 22 23]]
Numpy数组axis=1列拼接
# 1 按照行方向拼接,列增宽。
arr1=np.array([[1,2,3],[4,5,3],[11,12,13]])
arr2=np.array([[6,7,8],[21,22,23],[34,78,67]])
#行和列都要跟第一个数组一致。 print(np.concatenate([arr1,arr2],axis=1))
#结果
[[ 1 2 3 6 7 8]
[ 4 5 3 21 22 23]
[11 12 13 34 78 67]]
Pandas axis=0行拼接
Pandas的拼接和numpy类似。
# axis=0 行拼接,即列保持不变,行变多。
import pandas as pd
df1=pd.DataFrame([["张三",28],["李四",32],["王二",19]],columns=[ 'name','age',],index=['no_001','no_002','no_003']) df2=pd.DataFrame([["刘二",48],["宋五",32]],columns=[ 'name','age',],index=['no_004','no_005'])
print(pd.concat([df1,df2],axis=0))
#结果
name age
no_001 张三 28
no_002 李四 32
no_003 王二 19
no_004 刘二 48
no_005 宋五 32
Pandas axis=1列拼接
# axis=1列拼接,即行保持不变,列变多。在原有的姓名、年龄后追加等级列。
import pandas as pd
df1=pd.DataFrame([["张三",28],["李四",32],["王二",19]],columns=[ 'name','age',],index=['no_001','no_002','no_003'])
df2=pd.DataFrame([['A'],['B'],['C']],columns=['level'],index=['no_001','no_002','no_003'])
print(pd.concat([df1,df2],axis=1))
#结果
name age level
no_001 张三 28 A
no_002 李四 32 B
no_003 王二 19 C
Pandas重复索引拼接
# 特别的,如果拼接时索引出现重复,pandas会同时显示两个一样的索引。
import pandas as pd
df1=pd.DataFrame([["张三",28],["李四",32],["王二",19]],columns=[ 'name','age',],index=['no_001','no_002','no_003'])
df2=pd.DataFrame([["刘二",48],["宋五",32]],columns=[ 'name','age',],index=['no_001','no_002'])
print(pd.concat([df1,df2],axis=0))
print(pd.concat([df1,df2],axis=0,ignore_index=True))
#结果
name age
no_001 张三 28
no_002 李四 32
no_003 王二 19
no_001 刘二 48
no_002 宋五 32
Pandas忽略索引拼接
# 索引重复时通过ignore_index=True参数忽略索引
import pandas as pd
df1=pd.DataFrame([["张三",28],["李四",32],["王二",19]],columns=[ 'name','age',],index=['no_001','no_002','no_003'])
df2=pd.DataFrame([["刘二",48],["宋五",32]],columns=[ 'name','age',],index=['no_001','no_002'])
print(pd.concat([df1,df2],axis=0,ignore_index=True))
name age
0 张三 28
1 李四 32
2 王二 19
3 刘二 48
4 宋五 32
Pandas 多层维索引拼接
import pandas as pd
df1=pd.DataFrame([["张三",28],["李四",32],["王二",19]],columns=[ 'name','age',],index=['no_001','no_002','no_003'])
df2=pd.DataFrame([["刘二",48],["宋五",32]],columns=[ 'name','age',],index=['no_001','no_002'])
print(pd.concat([df1,df2],axis=0,keys=['one','two']))
#结果
name age
one no_001 张三 28
no_002 李四 32
no_003 王二 19
two no_001 刘二 48
no_002 宋五 32
Pandas 内连接方式拼接
#内连接方式(inner join)是对有相同的列做拼接,拼接时只通过相同的列名匹配。
import pandas as pd
df1=pd.DataFrame([["张三",28],["李四",32],["王二",19]],columns=[ 'name','age',],index=['no_001','no_002','no_003'])
df2=pd.DataFrame([["李四",32,'A'],["宋五",32,'B']],columns=[ 'name','age','level'],index=['no_001','no_002'])
print(pd.concat([df1,df2],axis=0,join="inner"))
#结果
name age
no_001 张三 28
no_002 李四 32
no_003 王二 19
no_001 李四 32
no_002 宋五 32
Pandas 外连接方式拼接
#外连接方式(outer join)是所有的列都参与拼接,期中列名不在主表的用NaN填充。
import pandas as pd
df1=pd.DataFrame([["张三",28],["李四",32],["王二",19]],columns=[ 'name','age',],index=['no_001','no_002','no_003'])
df2=pd.DataFrame([["李四",32,'A'],["宋五",32,'B']],columns=[ 'name','age','level'],index=['no_001','no_002'])
#这里因为有重复数据,所以加了个sort=True
print(pd.concat([df1,df2],axis=0,join="outer",sort=True))
#结果
age level name
no_001 28 NaN 张三
no_002 32 NaN 李四
no_003 19 NaN 王二
no_001 32 A 李四
no_002 32 B 宋五
Pandas join_axes连接方式拼接
#通过join_axes参数指定输出时的列名和顺序
import pandas as pd
df1=pd.DataFrame([["张三",28],["李四",32],["王二",19]],columns=[ 'name','age',],index=['no_001','no_002','no_003'])
df2=pd.DataFrame([["李四",32,'A'],["宋五",32,'B']],columns=[ 'name','age','level'],index=['no_001','no_002'])
print(pd.concat([df1,df2],axis=0,join_axes=[df2.columns]))
#结果
name age level
no_001 张三 28 NaN
no_002 李四 32 NaN
no_003 王二 19 NaN
no_001 李四 32 A
no_002 宋五 32 B
Pandas 追加方式拼接
# 通过append(追加)方式拼接,该方法是应用拼接的数据生成个新的对象而不是修改原有Pandas的数据。
import pandas as pd
df1=pd.DataFrame([["张三",28],["李四",32],["王二",19]],columns=['name','age',],index=['no_001','no_002','no_003'])
df2=pd.DataFrame([["李四",32],["宋五",32]],columns=['name','age'],index=['no_001','no_002'])
print(df1.append(df2))
#结果
name age
no_001 张三 28
no_002 李四 32
no_003 王二 19
no_001 李四 32
no_002 宋五 32
数据连接
数据连接主要是对行(列)名相同的元素进行关联,用两者列名相同的元素进行内容匹配。
Merge 内连接
Merge inner(内连接)方式时会按照两个DataFrame有相同的列名和值去匹配,有记录即返回。返回的列名不会出现重复。
import pandas as pd
df1=pd.DataFrame([["张三",28],["李四",32],["王二",19]],columns=['name','age',],index=['no_001','no_002','no_003'])
df2=pd.DataFrame([["李四",32,'A'],["王二",19,'B'],["王三",34,'C']],columns=['name','age','level'],index=['no_004','no_005','no_006'])
print(pd.merge(df1,df2,how='inner'))
#print(pd.merge(df1,df2)) #等价于上式
#print(df1.merge(df2)) #等价于上式
#结果
name age level
0 李四 32 A
1 王二 19 B
Merge 外连接
Merge outer(外连接)方式是会按照两个DataFrame有相同的列名和值去匹配,匹配不上的用NaN填充。返回的列名不会出现重复。
import pandas as pd
df1=pd.DataFrame([["张三",28],["李四",32],["王二",19]],columns=['name','age',],index=['no_001','no_002','no_003'])
df2=pd.DataFrame([["李四",32,'A'],["王二",19,'B'],["王三",34,'C']],columns=['name','age','level'],index=['no_004','no_005','no_006'])
print(pd.merge(df1,df2,how='outer'))
#print(df1.merge(df2,how='outer')) #等价于上式
#结果
name age level
0 张三 28 NaN
1 李四 32 A
2 王二 19 B
3 王三 34 C
Merge 左外连接
Merge left(左连接)方式是按照两个DataFrame有相同的列名和值去匹配,其中左边的为主表(返回记录同左表),匹配不上的用NaN填充。返回的列名不会出现重复。
同理right(右连接)与左连接类似。
import pandas as pd
df1=pd.DataFrame([["张三",28],["李四",32],["王二",19]],columns=['name','age',],index=['no_001','no_002','no_003'])
df2=pd.DataFrame([["李四",32,'A'],["王二",19,'B'],["王三",34,'C']],columns=['name','age','level'],index=['no_004','no_005','no_006'])
print(pd.merge(df1,df2,how='left'))
# print(df1.merge(df2,how='left')) 等价于上式
print(pd.merge(df1,df2,how='right'))
#结果
name age level
0 张三 28 NaN
1 李四 32 A
name age level
0 李四 32 A
1 王二 19 B
2 王三 34 C
Merge 指定key连接
如果要连接的字段名称不一样,那么就需要用指定key的方式去连接。
import pandas as pd
df1=pd.DataFrame([["张三",28],["李四",32],["王二",19]],columns=['name','age',],index=['no_001','no_002','no_003'])
df2=pd.DataFrame([["李四",32,'A'],["王二",19,'B'],["王三",34,'C']],columns=['title','year','level'],index=['no_004','no_005','no_006'])
print(pd.merge(df1,df2,left_on=["name","age"],right_on=["title","year"]))
#结果
name age title year level
0 李四 32 李四 32 A
1 王二 19 王二 19 B
Merge 指定key删除重复列连接
该方式在指定key连接的基础上会删除重复的列,即取连接里去重后的列名。
import pandas as pd
df1=pd.DataFrame([["张三",28],["李四",32],["王二",19]],columns=['name','age',],index=['no_001','no_002','no_003'])
df2=pd.DataFrame([["李四",32,'A'],["王二",19,'B'],["王三",34,'C']],columns=['title','year','level'],index=['no_004','no_005','no_006'])
print(pd.merge(df1,df2,left_on=["name","age"],right_on=["title","year"]).drop(["title","year"],axis=1))
#结果
name age level
0 李四 32 A
1 王二 19 B
Merge 指定索引连接
该方式是通过索引进行数据的连接,参数为left_index。如果想删除“重复”的列,接drop函数即可。见下例:
import pandas as pd
df1=pd.DataFrame([["张三",28],["李四",32],["王二",19]],columns=['name','age',],index=['no_001','no_002','no_003'])
df2=pd.DataFrame([["李四",32,'A'],["王二",19,'B'],["王三",34,'C']],columns=['title','year','level'],index=['no_004','no_002','no_003'])
print(pd.merge(df1,df2,left_index=True,right_index=True))
#指定要删除的列
print(pd.merge(df1,df2,left_index=True,right_index=True).drop(["title","year"],axis=1))
#结果
name age title year level
no_002 李四 32 王二 19 B
no_003 王二 19 王三 34 C
name age level
no_002 李四 32 B
no_003 王二 19 C
注:1 left_index(right_index)可以和right_on(left_on)混(一起)用。
Join实现数据连接
Pandas实现了join方法来进行数据的连接,不过需要注意的是,这里默认是按照索引连连接。
import pandas as pd
df1=pd.DataFrame([["张三",28],["李四",32],["王二",19],["王一",23]],columns=['name','age',],index=['no_001','no_002','no_003','no_004'])
df2=pd.DataFrame([["李四",32,'A'],["王二",19,'B'],["王三",34,'C'],["刘七",35,'A']],columns=['name','age','level'],index=['no_001','no_002','no_003','no_006'])
print(df1.join(df2,how="outer",rsuffix='_r'))
print(df1.join(df2,how="left",rsuffix='_r'))
print(df1.join(df2,how="inner",lsuffix='_l'))
print(df1.join(df2,how="inner",rsuffix='_r').drop(["name_r","age_r"],axis=1))
#结果
name age name_r age_r level
no_001 张三 28.0 李四 32.0 A
no_002 李四 32.0 王二 19.0 B
no_003 王二 19.0 王三 34.0 C
no_004 王一 23.0 NaN NaN NaN
no_006 NaN NaN 刘七 35.0 A
name age name_r age_r level
no_001 张三 28 李四 32.0 A
no_002 李四 32 王二 19.0 B
no_003 王二 19 王三 34.0 C
no_004 王一 23 NaN NaN NaN
name_l age_l name age level
no_001 张三 28 李四 32 A
no_002 李四 32 王二 19 B
no_003 王二 19 王三 34 C
name age level
no_001 张三 28 A
no_002 李四 32 B
no_003 王二 19 C
以上是关于Python数据分析pandas之数据拼接与连接的主要内容,如果未能解决你的问题,请参考以下文章
100天精通Python(数据分析篇)——第73天:Pandas文本数据处理方法之查找替换拼接正则虚拟变量
pandas读取多个excel文件并拼接(append)起来形成最终的dataframe与标签文件连接(join)形成最终学习数据集
Python数据分析库pandas ------ mergeconcatenation pd.concat合并与拼接