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合并与拼接

Pandas中DataFrame数据合并连接(concatmergejoin)之merge

python数据分析之pandas数据合并

python数据分析之pandas数据合并