Pandas基础(五):append、assign、combine、update、concat、merge、join
DataWhale第十二期组队学习:Python Pandas
这个方法主要是用于添加新的行
假设我们现在有这样一个表,是原来数据表的一部分
df_append = df.loc[:3,['Gender','Height']].copy()
Gender | Height | |
---|---|---|
0 | M | 173 |
1 | F | 192 |
2 | M | 186 |
3 | F | 167 |
例如:我想要添加新的一行
# 新构造的一个Series,name必须指定
s = pd.Series({
'Gender':'F','Height':188},name='new_row')
# 添加上去
df_append.append(s)
Gender | Height | |
---|---|---|
0 | M | 173 |
1 | F | 192 |
2 | M | 186 |
3 | F | 167 |
new_row | F | 188 |
例如:我想要添加新的多行
# 利用DataFrame添加多行
df_temp = pd.DataFrame({
'Gender':['F','M'],'Height':[188,176]},index=['new_1','new_2'])
df_append.append(df_temp)
Gender | Height | |
---|---|---|
0 | M | 173 |
1 | F | 192 |
2 | M | 186 |
3 | F | 167 |
new_1 | F | 188 |
new_2 | M | 176 |
用于添加新的列,列名直接由参数指定
原始的数据表依然和上一小节中一样,但需要添加的是列了
例如:我想要添加新的一列
s = pd.Series(list('abcd'),index=range(4))
df_append.assign(Letter=s)
Gender | Height | Letter | |
---|---|---|---|
0 | M | 173 | a |
1 | F | 192 | b |
2 | M | 186 | c |
3 | F | 167 | d |
例如:我想要添加新的多列
df_append.assign(col1=lambda x:x['Gender']*2,col2=s)
Gender | Height | col1 | col2 | |
---|---|---|---|---|
0 | M | 173 | MM | a |
1 | F | 192 | FF | b |
2 | M | 186 | MM | c |
3 | F | 167 | FF | d |
comine和update都是用于表的填充函数,可以根据某种规则填充
通过一个指定的方法对两个Dataframe
进行合并,比如下面这个例子
例如:根据均值的大小进行组合
# 例子1
df1 = pd.DataFrame({
'A': [1, 2], 'B': [6, 5]})
df2 = pd.DataFrame({
'A': [8, 7], 'B': [3, 4]})
df1.combine(df2,lambda x,y:x if x.mean()>y.mean() else y)
组合的时候是逐列进行的,即先比较两者A的均值,再比较两者B的均值
那么最后的结果应该是取df2的A列,取df1的B列
A | B | |
---|---|---|
0 | 8 | 6 |
1 | 7 | 5 |
要注意的一个点就是这里有一个索引对齐的特性,如果我将B的行与列都改一下索引
例如:索引对不齐时的组合
# 行的索引变为1,2,列的索引变为B、C
df2 = pd.DataFrame({
'B': [8, 7], 'C': [6, 5]},index=[1,2])
df1.combine(df2,lambda x,y:x if x.mean()>y.mean() else y)
这里唯一有交集的就是B列,通过比较,df2中的均值大,所以保留B列
如果这里是A列均值大,那么这个新表中的B列,应该是0,1处为df1的B的值,2处为NaN
因为df2为优先列,所以非重合的部分保留了df2的值
A | B | C | |
---|---|---|---|
0 | NaN | NaN | NaN |
1 | NaN | 8.0 | 3.0 |
2 | NaN | 7.0 | 4.0 |
但是我A的值怎么就全没了,如果我要保留符合条件的值呢
例如:保留存在于A但是不存在于B的值
df1.combine(df2,lambda x,y:x if x.mean()>y.mean() else y,overwrite=False)
A | B | C | |
---|---|---|---|
0 | 1.0 | NaN | NaN |
1 | 2.0 | 8.0 | 3.0 |
2 | NaN | 7.0 | 4.0 |
这个方法作用是用df2填补df1的缺失值
例如:填充原表中的None值
df1 = pd.DataFrame({
'A': [None, 0], 'B': [None, 4]})
df2 = pd.DataFrame({
'A': [1, 1], 'B': [3, 3]})
df1.combine_first(df2)
A | B | |
---|---|---|
0 | 1.0 | 3.0 |
1 | 0.0 | 4.0 |
例如:填充时索引对不齐
那就能填的地方填
df1 = pd.DataFrame({
'A': [None, 0], 'B': [4, None]})
df2 = pd.DataFrame({
'B': [3, 3], 'C': [1, 1]}, index=[1, 2])
df1.combine_first(df2)
A | B | C | |
---|---|---|---|
0 | NaN | 4.0 | NaN |
1 | 0.0 | 3.0 | 1.0 |
2 | NaN | 3.0 | 1.0 |
用第二个表去更新第一个表中的内容
例如:更新原表中的某一列
df1 = pd.DataFrame({
'A': [1, 2, 3],
'B': [400, 500, 600]})
df2 = pd.DataFrame({
'B': [4, 5, 6],
'C': [7, 8, 9]})
df1.update(df2)
df1
如果5这个数字位置是NaN值,那就还是保留df1中的500
A | B | |
---|---|---|
0 | 1 | 4 |
1 | 2 | 5 |
2 | 3 | 6 |
例如:部分更新原表
df1 = pd.DataFrame({
'A': ['a', 'b', 'c'],
'B': ['x', 'y', 'z']})
df2 = pd.DataFrame({
'B': ['d', 'e']}, index=[1,2])
df1.update(df2)
df1
A | B | |
---|---|---|
0 | a | x |
1 | b | d |
2 | c | e |
concat
方法可以在两个维度上拼接,默认纵向拼接(axis=0),拼接方式默认外连接
所谓外连接,就是取拼接方向的并集,而inner
时取拼接方向(若使用默认的纵向拼接,则为列的交集)的交集
这里先生成三个例子
df1 = pd.DataFrame({
'A': ['A0', 'A1'],
'B': ['B0', 'B1']},
index = [0,1])
df2 = pd.DataFrame({
'A': ['A2', 'A3'],
'B': ['B2', 'B3']},
index = [2,3])
df3 = pd.DataFrame({
'A': ['A1', 'A3'],
'D': ['D1', 'D3'],
'E': ['E1', 'E3']},
index = [1,3])
例如:将df1和df2两个进行拼接
pd.concat([df1,df2])
A | B | |
---|---|---|
0 | A0 | B0 |
1 | A1 | B1 |
2 | A2 | B2 |
3 | A3 | B3 |
例如:我想要横向对齐
pd.concat([df1,df2],axis=1)
A | B | A | B | |
---|---|---|---|---|
0 | A0 | B0 | NaN | NaN |
1 | A1 | B1 | NaN | NaN |
2 | NaN | NaN | A2 | B2 |
3 | NaN | NaN | A3 | B3 |
例如:取df1和df3的交集
pd.concat([df3,df1],join='inner')
默认还是列排列
A | |
---|---|
1 | A1 |
3 | A3 |
0 | A0 |
1 | A1 |
例如:给列添加一个Series
s = pd.Series(['X0', 'X1'], name='X')
pd.concat([df1,s],axis=1)
A | B | X | |
---|---|---|---|
0 | A0 | B0 | X0 |
1 | A1 | B1 | X1 |
merge函数的作用是将两个pandas对象横向合并,遇到重复的索引项时会使用笛卡尔积,默认inner连接,可选left、outer、right连接
所谓左连接,就是指以第一个表索引为基准,右边的表中如果不再左边的则不加入,如果在左边的就以笛卡尔积的方式加入
merge/join与concat的不同之处在于on参数,可以指定某一个对象为key来进行连接
left = pd.DataFrame({
'key1': ['K0', 'K0', 'K1', 'K2'],
'key2': ['K0', 'K1', 'K0', 'K1'],
'A': ['A0', 'A1', 'A2', 'A3'],
'B': ['B0', 'B1', 'B2', 'B3']})
right = pd.DataFrame({
'key1': ['K0', 'K1', 'K1', 'K2'],
'key2': ['K0', 'K0', 'K0', 'K0'],
'C': ['C0', 'C1', 'C2', 'C3'],
'D': ['D0', 'D1', 'D2', 'D3']})
right2 = pd.DataFrame({
'key1': ['K0', 'K1', 'K1', 'K2'],
'key2': ['K0', 'K0', 'K0', 'K0'],
'C': ['C0', 'C1', 'C2', 'C3']})
例如:连接左与右两个表格
pd.merge(left, right, on='key1')
以key1为准则连接,如果具有相同的列,则默认suffixes=('_x','_y')
可以理解为将两个数据库进行合并,合并的标准为key1
key1 | key2_x | A | B | key2_y | C | D | |
---|---|---|---|---|---|---|---|
0 | K0 | K0 | A0 | B0 | K0 | C0 | D0 |
1 | K0 | K1 | A1 | B1 | K0 | C0 | D0 |
2 | K1 | K0 | A2 | B2 | K0 | C1 | D1 |
3 | K1 | K0 | A2 | B2 | K0 | C2 | D2 |
4 | K2 | K1 | A3 | B3 | K0 | C3 | D3 |
例如:左连接
pd.merge(left, right, how='left', on=['key1', 'key2'])
key1 | key2 | A | B | C | D | |
---|---|---|---|---|---|---|
0 | K0 | K0 | A0 | B0 | C0 | D0 |
1 | K0 | K1 | A1 | B1 | NaN | NaN |
2 | K1 | K0 | A2 | B2 | C1 | D1 |
3 | K1 | K0 | A2 | B2 | C2 | D2 |
4 | K2 | K1 | A3 | B3 | NaN | NaN |
例如:右连接
pd.merge(left, right, how='right', on=['key1', 'key2'])
key1 | key2 | A | B | C | D | |
---|---|---|---|---|---|---|
0 | K0 | K0 | A0 | B0 | C0 | D0 |
1 | K1 | K0 | A2 | B2 | C1 | D1 |
2 | K1 | K0 | A2 | B2 | C2 | D2 |
3 | K2 | K0 | NaN | NaN | C3 | D3 |
join函数作用是将多个pandas对象横向拼接,遇到重复的索引项时会使用笛卡尔积,默认左连接,可选inner、outer、right连接
left = pd.DataFrame({
'A': ['A0', 'A1', 'A2'],
'B': ['B0', 'B1', 'B2']},
index=['K0', 'K1', 'K2'])
right = pd.DataFrame({
'C': ['C0', 'C2', 'C3'],
'D': ['D0', 'D2', 'D3']},
index=['K0', 'K2', 'K3'])
left.join(right)
A | B | C | D | |
---|---|---|---|---|
K0 | A0 | B0 | C0 | D0 |
K1 | A1 | B1 | NaN | NaN |
K2 | A2 | B2 | C2 | D2 |
对于many_to_one模式下的合并,往往join更为方便
同样可以指定key
left = pd.DataFrame({
'A': ['A0', 'A1', 'A2', 'A3'],
'B': ['B0', 'B1', 'B2', 'B3'],
'key': ['K0', 'K1', 'K0', 'K1']})
right = pd.DataFrame({
'C': ['C0', 'C1'],
'D': ['D0', 'D1']},
index=['K0', 'K1'])
left.join(right, on='key')
A | B | key | C | D | |
---|---|---|---|---|---|
0 | A0 | B0 | K0 | C0 | D0 |
1 | A1 | B1 | K1 | C1 | D1 |
2 | A2 | B2 | K0 | C0 | D0 |
3 | A3 | B3 | K1 | C1 | D1 |
多层key
A | B | key1 | key2 | C | D | |
---|---|---|---|---|---|---|
0 | A0 | B0 | K0 | K0 | C0 | D0 |
1 | A1 | B1 | K0 | K1 | NaN | NaN |
2 | A2 | B2 | K1 | K0 | C1 | D1 |
3 | A3 | B3 | K2 | K1 | C3 | D3 |