python--pandas合并与连接

合并与连接操作是数据处理中常见的,在pandas中用concat或append方法实现数据框的合并操作,
用merge或join方法实现数据框的连接操作。

环境

  • python3.9
  • win10 64bit
  • pandas==1.2.1

append

append方法根据行在原数据框添加新的数据框。

import pandas as pd
pd.set_option('display.notebook_repr_html',False)
# 数据准备
df = pd.DataFrame([[1, 2], [3, 4]], columns=list('AB'))
df2 = pd.DataFrame([[5, 6], [7, 8]], columns=list('AB'))
df
   A  B
0  1  2
1  3  4
df2
   A  B
0  5  6
1  7  8
# 行末添加新数据框
df.append(df2)
   A  B
0  1  2
1  3  4
0  5  6
1  7  8

如果想要合并后的数据框索引重写排序,可以设置参数ignore_index=True

# 行末添加新数据框(索引重新排序)
df.append(df2,ignore_index=True)
   A  B
0  1  2
1  3  4
2  5  6
3  7  8

concat

concat函数是panda自带的,可以按行或按列合并多个pandas数据框。

# 数据准备
df1 = pd.DataFrame([['a', 1], ['b', 2]],columns=['letter', 'number'])
df2 = pd.DataFrame([['c', 3], ['d', 4]],columns=['letter', 'number'])
df3 = pd.DataFrame([['c', 3, 'cat'], ['d', 4, 'dog']],columns=['letter', 'number', 'animal'])
df1
  letter  number
0      a       1
1      b       2
df2
  letter  number
0      c       3
1      d       4
df3
  letter  number animal
0      c       3    cat
1      d       4    dog

按行合并多个数据框,需要注意的是objs参数接受一个可迭代对象。concat函数默认按行合并。

# 按行合并
pd.concat(objs=[df1,df2])
  letter  number
0      a       1
1      b       2
0      c       3
1      d       4

设置ignore_index=True,使合并后的数据框索引重新排序。

# 按行合并(索引重排序)
pd.concat([df1,df2],ignore_index=True)
  letter  number
0      a       1
1      b       2
2      c       3
3      d       4

按行合并时,concat对所有的列进行全连接(参数join='outer'),没有的列会填充为NaN。

pd.concat([df1,df3])
  letter  number animal
0      a       1    NaN
1      b       2    NaN
0      c       3    cat
1      d       4    dog

设置参数join='inner',可以只保留共有的列。

pd.concat([df1,df3],join='inner')
  letter  number
0      a       1
1      b       2
0      c       3
1      d       4

设置参数axis=1axis='columns',可以按列合并多个数据框。

# 按列合并数据框
pd.concat([df1,df2],axis=1)
  letter  number letter  number
0      a       1      c       3
1      b       2      d       4

merge

merge方法根据列或索引连接数据框。

# 数据准备
df1 = pd.DataFrame({'key': ['a', 'b', 'c'],
                    'value1': [1, 2, 3]})
df2 = pd.DataFrame({'key': ['b', 'c', 'd'],
                    'value2': [5, 6, 7]})
df1
  key  value1
0   a       1
1   b       2
2   c       3
df2
  key  value2
0   b       5
1   c       6
2   d       7

当两个数据框只有一个相同列时,merge方法会自动根据相同列进行内连接,on参数可以省略。

# 内连接,默认相同列连接
df1.merge(df2)
  key  value1  value2
0   b       2       5
1   c       3       6
# 内连接,指定列连接
df1.merge(df2,on='key')
  key  value1  value2
0   b       2       5
1   c       3       6

设置参数how=['left','right','outer','inner','cross'],可以完成不同类型的连接。

# 外连接
df1.merge(df2,how='outer')
  key  value1  value2
0   a     1.0     NaN
1   b     2.0     5.0
2   c     3.0     6.0
3   d     NaN     7.0
# 左连接
df1.merge(df2,how='left')
  key  value1  value2
0   a       1     NaN
1   b       2     5.0
2   c       3     6.0
# 右连接
df1.merge(df2,how='right')
  key  value1  value2
0   b     2.0       5
1   c     3.0       6
2   d     NaN       7
# 交叉连接
df1.merge(df2,how='cross')
  key_x  value1 key_y  value2
0     a       1     b       5
1     a       1     c       6
2     a       1     d       7
3     b       2     b       5
4     b       2     c       6
5     b       2     d       7
6     c       3     b       5
7     c       3     c       6
8     c       3     d       7

当两个数据框没有相同列时,需要设置left_onright_on参数,表示按这两列进行连接。

# 数据准备
df3 = pd.DataFrame({'lkey': ['a', 'b', 'c'],
                    'value1': [1, 2, 3]})
df4 = pd.DataFrame({'rkey': ['b', 'c', 'd'],
                    'value2': [5, 6, 7]})
df3
  lkey  value1
0    a       1
1    b       2
2    c       3
df4
  rkey  value2
0    b       5
1    c       6
2    d       7
# 指定列内连接
df3.merge(df4, left_on='lkey', right_on='rkey')
  lkey  value1 rkey  value2
0    b       2    b       5
1    c       3    c       6

如果需要根据数据框的索引进行连接,需要根据需求设置参数left_index=True或者right_index=True

# 数据准备
df5 = pd.DataFrame({'lkey': ['a', 'b', 'c'],
                    'value1': [1, 2, 3]})
df6 = pd.DataFrame({'rkey': ['b', 'c', 'd'],
                    'value2': [5, 6, 7]},index=range(1,4))
df5
  lkey  value1
0    a       1
1    b       2
2    c       3
df6
  rkey  value2
1    b       5
2    c       6
3    d       7
# 按索引连接
df5.merge(df6,left_index=True,right_index=True)
  lkey  value1 rkey  value2
1    b       2    b       5
2    c       3    c       6

设置suffixes,可以给相同的列名添加后缀。默认后缀是_x,_y

# 数据准备
df7 = pd.DataFrame({'key': ['a', 'b', 'c'],
                    'value': [1, 2, 3]})
df8 = pd.DataFrame({'key': ['b', 'c', 'd'],
                    'value': [5, 6, 7]})
df7
  key  value
0   a      1
1   b      2
2   c      3
df8
  key  value
0   b      5
1   c      6
2   d      7
# 连接后设置相同列后缀
df7.merge(df8,on='key',suffixes=['_A','_B'])
  key  value_A  value_B
0   b        2        5
1   c        3        6

join

join方法与merge方法作用相同,基本上merge方法已经可以完成所有的连接操作。
join方法对按索引连接更方便而已。

# 数据准备
df1 = pd.DataFrame({'lkey': ['a', 'b', 'c'],
                    'value1': [1, 2, 3]},index=range(1,4))
df2 = pd.DataFrame({'rkey': ['b', 'c', 'd'],
                    'value2': [5, 6, 7]},index=range(2,5))
df1
  lkey  value1
1    a       1
2    b       2
3    c       3
df2
  rkey  value2
2    b       5
3    c       6
4    d       7

当连接的两个数据框中没有相同列时,可以直接按索引进行左连接。

# 通过索引左连接
df1.join(df2)
  lkey  value1 rkey  value2
1    a       1  NaN     NaN
2    b       2    b     5.0
3    c       3    c     6.0

同样,可以设置how参数,控制连接的行为。

# 通过索引内连接
df1.join(df2,how='inner')
  lkey  value1 rkey  value2
2    b       2    b       5
3    c       3    c       6

当数据框中有相同列时,需要设置后缀。

# 数据准备
df3 = pd.DataFrame({'key': ['a', 'b', 'c'],
                    'value1': [1, 2, 3]},index=range(1,4))
df4 = pd.DataFrame({'key': ['b', 'c', 'd'],
                    'value2': [5, 6, 7]},index=range(2,5))
# 为相同列设置后缀
df3.join(df4,lsuffix='_x',rsuffix='_y')
  key_x  value1 key_y  value2
1     a       1   NaN     NaN
2     b       2     b     5.0
3     c       3     c     6.0
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,423评论 6 491
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,147评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,019评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,443评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,535评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,798评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,941评论 3 407
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,704评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,152评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,494评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,629评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,295评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,901评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,742评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,978评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,333评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,499评论 2 348

推荐阅读更多精彩内容