pandas的拼接分为两种:
- 级联:pd.concat, pd.append
- 合并:pd.merge, pd.join
In [1]:
import numpy as np
import pandas as pd
from pandas import Series,DataFrame
0. 回顾numpy的级联
============================================
练习12:
- 生成2个3*3的矩阵,对其分别进行两个维度上的级联
============================================
In [2]:
n1 = np.random.randint(0,9,size = (3,3))
n2 = np.random.randint(-9,0,size = (3,3))
In [3]:
display(n1,n2)
np.concatenate([n1,n2])
array([[7, 4, 8],
[3, 2, 2],
[1, 4, 7]])
array([[-3, -5, -3],
[-4, -2, -3],
[-7, -2, -5]])
Out[3]:
array([[ 7, 4, 8],
[ 3, 2, 2],
[ 1, 4, 7],
[-3, -5, -3],
[-4, -2, -3],
[-7, -2, -5]])
为方便讲解,我们首先定义一个生成DataFrame的函数:
In [4]:
def make_df(inds,cols):
#字典的key作为列名进行展示
dic = {key:[key+str(i) for i in inds]for key in cols}
df = DataFrame(dic,index = inds)
return df
In [5]:
make_df([1,2],list('AB'))
Out[5]:
|
A |
B |
1 |
A1 |
B1 |
2 |
A2 |
B2 |
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)
In [6]:
df1 = make_df([1,2],list('AB'))
df2 = make_df([3,4],list('AB'))
In [7]:
display(df1,df2)
pd.concat([df1,df2])
|
A |
B |
1 |
A1 |
B1 |
2 |
A2 |
B2 |
|
A |
B |
3 |
A3 |
B3 |
4 |
A4 |
B4 |
Out[7]:
|
A |
B |
1 |
A1 |
B1 |
2 |
A2 |
B2 |
3 |
A3 |
B3 |
4 |
A4 |
B4 |
可以通过设置axis来改变级联方向
In [8]:
pd.concat((df1,df2),axis = 1)
Out[8]:
|
A |
B |
A |
B |
1 |
A1 |
B1 |
NaN |
NaN |
2 |
A2 |
B2 |
NaN |
NaN |
3 |
NaN |
NaN |
A3 |
B3 |
4 |
NaN |
NaN |
A4 |
B4 |
注意index在级联时可以重复
In [9]:
df3 = make_df([0,1,2],list('AB'))
df4 = make_df([1,2,3],list('AB'))
In [10]:
df5 = pd.concat([df3,df4])
df5
Out[10]:
|
A |
B |
0 |
A0 |
B0 |
1 |
A1 |
B1 |
2 |
A2 |
B2 |
1 |
A1 |
B1 |
2 |
A2 |
B2 |
3 |
A3 |
B3 |
In [11]:
df5.loc[[1,2]]
Out[11]:
|
A |
B |
1 |
A1 |
B1 |
1 |
A1 |
B1 |
2 |
A2 |
B2 |
2 |
A2 |
B2 |
In [12]:
#列名,肯定是不建议相同(属性),行名是可以相同的(比如,人的姓名)
df = DataFrame(np.random.randint(0,10,size = (2,2)),columns = ['张三','张三'],index = ['A','B'])
df
Out[12]:
|
张三 |
张三 |
A |
8 |
2 |
B |
9 |
8 |
也可以选择忽略ignore_index,重新索引
In [13]:
#ignore_index,重新创建从0开始(逐个+1增大)的数字索引
pd.concat([df3,df4],ignore_index=True)
Out[13]:
|
A |
B |
0 |
A0 |
B0 |
1 |
A1 |
B1 |
2 |
A2 |
B2 |
3 |
A1 |
B1 |
4 |
A2 |
B2 |
5 |
A3 |
B3 |
或者使用多层索引 keys
concat([x,y],keys=['x','y'])
In [14]:
#keys=['x','y']创建第一层索引,keys可以让合并后的数据更加清晰
x = make_df(['A','B'],list('XY'))
y = make_df(['a','b'],list('XY'))
pd.concat([x,y],keys = ['x','y'])
Out[14]:
|
|
X |
Y |
x |
A |
XA |
YA |
B |
XB |
YB |
|
y |
a |
Xa |
Ya |
b |
Xb |
Yb |
In [15]:
#使用之前创建的df1,df2,也是一样
pd.concat([df1,df2],keys=['x','y'])
Out[15]:
|
|
A |
B |
x |
1 |
A1 |
B1 |
2 |
A2 |
B2 |
|
y |
3 |
A3 |
B3 |
4 |
A4 |
B4 |
In [ ]:
#pd 模块 import pandas as pd
#df1,df2 具体的实例
#级联的方法,属于上一级,DataFrame来自pandas
============================================
练习13:
想一想级联的应用场景?
使用昨天的知识,建立一个期中考试张三、李四的成绩表ddd
假设新增考试学科"计算机",如何实现?
新增王老五同学的成绩,如何实现?
============================================
2) 不匹配级联
不匹配指的是级联的维度的索引不一致。例如纵向级联时列索引不一致,横向级联时行索引不一致
In [16]:
df7 = make_df([1,2,3],list('AB'))
df8 = make_df([3,4],list('BCD'))
display(df7,df8)
|
A |
B |
1 |
A1 |
B1 |
2 |
A2 |
B2 |
3 |
A3 |
B3 |
|
B |
C |
D |
3 |
B3 |
C3 |
D3 |
4 |
B4 |
C4 |
D4 |
In [17]:
df9 = make_df([1,2,3],list('ABC'))
df10 = make_df([4,5,6],list('BCD'))
display(df9,df10)
|
A |
B |
C |
1 |
A1 |
B1 |
C1 |
2 |
A2 |
B2 |
C2 |
3 |
A3 |
B3 |
C3 |
|
B |
C |
D |
4 |
B4 |
C4 |
D4 |
5 |
B5 |
C5 |
D5 |
6 |
B6 |
C6 |
D6 |
有3种连接方式:
- 外连接:补NaN(默认模式)
- 内连接:只连接匹配的项
- 连接指定轴 join_axes
In [18]:
#外连接:补NaN(默认模式)
pd.concat([df7,df8])
Out[18]:
|
A |
B |
C |
D |
1 |
A1 |
B1 |
NaN |
NaN |
2 |
A2 |
B2 |
NaN |
NaN |
3 |
A3 |
B3 |
NaN |
NaN |
3 |
NaN |
B3 |
C3 |
D3 |
4 |
NaN |
B4 |
C4 |
D4 |
In [19]:
#内连接:只连接匹配的项
pd.concat((df7,df8),join = 'inner',axis = 1)
Out[19]:
|
A |
B |
B |
C |
D |
3 |
A3 |
B3 |
B3 |
C3 |
D3 |
In [20]:
#连接指定轴 join_axes,某一个DataFrame列索引,作为,新的列索引值
pd.concat((df9,df10),join_axes = [df10.columns])
#新版本pandas已经删除了join_axes
---------------------------------------------------------------------------TypeError Traceback (most recent call last)<ipython-input-20-d4b5758fa6e1> in <module> 1 #连接指定轴 join_axes,某一个DataFrame列索引,作为,新的列索引值----> 2 pd.concat((df9,df10),join_axes = [df10.columns]) 3 #新版本pandas已经删除了join_axes
TypeError: concat() got an unexpected keyword argument 'join_axes'
============================================
练习14:
假设【期末】考试ddd2的成绩没有张三的,只有李四、王老五、赵小六的,使用多种方法级联
============================================
3) 使用append()函数添加
由于在后面级联的使用非常普遍,因此有一个函数append专门用于在后面添加
In [21]:
df11 = make_df([0,1,2,3,4],['大众','福克斯'])
df12 = make_df([5,6,7,8,9],['大众','福克斯'])
display(df11,df12)
|
大众 |
福克斯 |
0 |
大众0 |
福克斯0 |
1 |
大众1 |
福克斯1 |
2 |
大众2 |
福克斯2 |
3 |
大众3 |
福克斯3 |
4 |
大众4 |
福克斯4 |
|
大众 |
福克斯 |
5 |
大众5 |
福克斯5 |
6 |
大众6 |
福克斯6 |
7 |
大众7 |
福克斯7 |
8 |
大众8 |
福克斯8 |
9 |
大众9 |
福克斯9 |
In [22]:
#使用append()函数添加,直接调用对象,相对要更加灵活、方便
df11.append(df12)
Out[22]:
|
大众 |
福克斯 |
0 |
大众0 |
福克斯0 |
1 |
大众1 |
福克斯1 |
2 |
大众2 |
福克斯2 |
3 |
大众3 |
福克斯3 |
4 |
大众4 |
福克斯4 |
5 |
大众5 |
福克斯5 |
6 |
大众6 |
福克斯6 |
7 |
大众7 |
福克斯7 |
8 |
大众8 |
福克斯8 |
9 |
大众9 |
福克斯9 |
In [23]:
#append函数属于DataFrame,concat这函数属于pandas模块
pd.concat((df11,df12))
Out[23]:
|
大众 |