pandas之DataFrame合並merge


一、merge

merge操作實現兩個DataFrame之間的合並,類似於sql兩個表之間的關聯查詢。merge的使用方法及參數解釋如下:

pd.merge(left, right, on=None, how='inner', left_on=None, right_on=None, left_index=False, right_index=False, 
   sort=False, suffixes=('_x', '_y'), copy=True, indicator=False, validate=None)
  • left和right:第一個DataFrame和第二個DataFrame對象,merge只能實現兩個DataFrame的合並,無法一次實現多個合並
  • on:指定參考column,要求兩個df必須至少有一個相同的column,默認為None以最多相同的column為參考
  • how:合並的方式,默認為inner取參考column的交集,outer取並集保留所有行;outer、left、right中的缺失值都以NaN填充;left按照左邊對象為參考進行合並即保留左邊的所有行,right按照右邊對象為參考進行合並即保留右邊所有行,
  • left_on=None和right_on=None:以上on是在兩個df有相同的column的情況下使用,如果兩個df沒有相同的column,使用left_on和right_on分別指明左邊和右邊的參考column
  • left_index和right_index:指定是否以索引為參考進行合並
  • sort:合並結果是否按on指定的參考進行排序
  • suffixed:合並后如果有重復column,分別加上什么后綴 

 

下面對每個參數進行演示

on:指定參考column,如果不指定默認為None,以兩者相同列的最多數為參考;index重新生成為從0開始的整數。

df1 = pd.DataFrame({'key1':['a','b','c','d'],'key2':['e','f','g','h'],'key3':['i','j','k','l']},index=['k','l','m','n',])
df2 = pd.DataFrame({'key1':['a','B','c','d'],'key2':['e','f','g','H'],'key4':['i','j','K','L']},index = ['p','q','u','v'])
print(df1)
print(df2)
print(pd.merge(df1,df2,on='key1'))
print(pd.merge(df1,df2,on='key2'))
print(pd.merge(df1,df2,on=['key1','key2']))
print(pd.merge(df1,df2))  #可以看到不加on參數,系統自動以個數最多的相同column為參考
#   key1 key2 key3
# k    a    e    i
# l    b    f    j
# m    c    g    k
# n    d    h    l
#   key1 key2 key4
# p    a    e    i
# q    B    f    j
# u    c    g    K
# v    d    H    L
#   key1 key2_x key3 key2_y key4
# 0    a      e    i      e    i
# 1    c      g    k      g    K
# 2    d      h    l      H    L
#   key1_x key2 key3 key1_y key4
# 0      a    e    i      a    i
# 1      b    f    j      B    j
# 2      c    g    k      c    K
#   key1 key2 key3 key4
# 0    a    e    i    i
# 1    c    g    k    K
#   key1 key2 key3 key4
# 0    a    e    i    i
# 1    c    g    k    K
參數on演示

 

how:指定合並方式,如果不指定默認為inner

inner相當於sql中的=,outer相當於sql中的full join,left相當於sql中的left join,right相當於sql中的right join;index重新生成為從0開始的整數。

對於outer、left、right來說可能會出現缺失值,全部以NaN填充。

df1 = pd.DataFrame({'key1':['a','b','c','d'],'key2':['e','f','g','h'],'key3':['i','j','k','l']},index=['k','l','m','n',])
df2 = pd.DataFrame({'key1':['a','B','c','d'],'key2':['e','f','g','H'],'key4':['i','j','K','L']},index = ['p','q','u','v'])
print(df1)
print(df2)
print(pd.merge(df1,df2,how='inner'))   #默認方式,取交集
print(pd.merge(df1,df2,how='outer'))   #取並集
print(pd.merge(df1,df2,how='left'))    #以左邊為參考,即保留左邊所有行
print(pd.merge(df1,df2,how='right'))   #以右邊為參考,即保留右邊所有行
#   key1 key2 key3
# k    a    e    i
# l    b    f    j
# m    c    g    k
# n    d    h    l
#   key1 key2 key4
# p    a    e    i
# q    B    f    j
# u    c    g    K
# v    d    H    L
#   key1 key2 key3 key4
# 0    a    e    i    i
# 1    c    g    k    K
#   key1 key2 key3 key4
# 0    a    e    i    i
# 1    b    f    j  NaN
# 2    c    g    k    K
# 3    d    h    l  NaN
# 4    B    f  NaN    j
# 5    d    H  NaN    L
#   key1 key2 key3 key4
# 0    a    e    i    i
# 1    b    f    j  NaN
# 2    c    g    k    K
# 3    d    h    l  NaN
#   key1 key2 key3 key4
# 0    a    e    i    i
# 1    c    g    k    K
# 2    B    f  NaN    j
# 3    d    H  NaN    L
參數how演示

 

left_on和right_on:默認都為False,但是如果兩個DataFrame沒有相同的column而又需要對它們的按列合並,則需要使用left_on和right_on分別指明兩邊的參考列;index重新生成為從0開始的整數。

但是left_on和right_on不是必須成對出現,下面關於left_index和right_index會涉及到。

df1 = pd.DataFrame({'key1':['a','b','c','d'],'key2':['e','f','g','h'],'key3':['i','j','k','l']},index=['k','l','m','n'])
df2 = pd.DataFrame({'key4':['a','B','c','d'],'key5':['e','f','g','H'],'key6':['i','j','K','L']},index = ['p','q','u','v'])
print(df1)
print(df2)
# print(pd.merge(df1,df2,df1 = pd.DataFrame({'key1':['a','b','c','d'],'key2':['e','f','g','h'],'key3':['i','j','k','l']},index=['k','l','m','n'])
df2 = pd.DataFrame({'key4':['a','B','c','d'],'key5':['e','f','g','H'],'key6':['i','j','K','L']},index = ['p','q','u','v'])
print(df1)
print(df2)
# print(pd.merge(df1,df2,left_on='key1',right_on='key4'))
#   key1 key2 key3
# k    a    e    i
# l    b    f    j
# m    c    g    k
# n    d    h    l
#   key4 key5 key6
# p    a    e    i
# q    B    f    j
# u    c    g    K
# v    d    H    L
#   key1 key2 key3 key4 key5 key6
# 0    a    e    i    a    e    i
# 1    c    g    k    c    g    K
# 2    d    h    l    d    H    L='key1',right_on='key4'))
#   key1 key2 key3
# k    a    e    i
# l    b    f    j
# m    c    g    k
# n    d    h    l
#   key4 key5 key6
# p    a    e    i
# q    B    f    j
# u    c    g    K
# v    d    H    L
#   key1 key2 key3 key4 key5 key6
# 0    a    e    i    a    e    i
# 1    c    g    k    c    g    K
# 2    d    h    l    d    H    L
參數left_on和right_on演示

 

left_index和right_index:默認都為False,如果需要按索引進行合並,則需要使用left_index和right_index指明以index為參考。(on、left_on、right_on都是指定以column為參考)

如果使用了left_index或者right_index,必須指明另一方的參考鍵。

結果除了包含兩個DataFrame的所有列,還會生成一個新的列,新列即以指定的兩個參考進行合並后的結果。

如果是left_on =  '**' 和right_index = True或者left_index =  True 和right_on = '**',index取on所在的一方,如果是left_index =  True和right_index = True,取兩者相同的即可。

df1 = pd.DataFrame({'key1':['a','b','c','d'],'key2':['e','f','g','h']},index=['k','l','m','n'])
df2 = pd.DataFrame({'key1':['k',6,'l']},index=['a','m','c'])
print(df1)
print(df2)
print(pd.merge(df1,df2,left_on='key1',right_index=True))  #index取df1的
print(pd.merge(df1,df2,left_index=True,right_on='key1'))   #index取df2的
print(pd.merge(df1,df2,left_index=True,right_index=True))  #index取兩者交集
#   key1 key2
# k    a    e
# l    b    f
# m    c    g
# n    d    h
#   key1
# a    k
# m    6
# c    l
#   key1 key1_x key2 key1_y
# k    a      a    e      k
# m    c      c    g      l
#   key1 key1_x key2 key1_y
# a    k      a    e      k
# c    l      b    f      l
#   key1_x key2 key1_y
# m      c    g      6
參數left_index和right_index演示

 

sort:結果是否按照參考進行排序,默認不排序;數字按照大小排序,字符串按照A-Za-z排序。

merge結果的顯示順序默認是按照df1、df2的行順序進行顯示,

df1 = pd.DataFrame({'key1':['d','a','c','B'],'key2':[3,6,1,8]},index=['k','l','m','n'])
df2 = pd.DataFrame({'key1':['c','B','a','d'],'key2':[3,8,2,1]},index = ['p','q','u','v'])
print(df1)
print(df2)
print(pd.merge(df1,df2,on='key2',))
print(pd.merge(df1,df2,on='key1',sort=True))
#   key1  key2
# k    d     3
# l    a     6
# m    c     1
# n    B     8
#   key1  key2
# p    c     3
# q    B     8
# u    a     2
# v    d     1
#   key1_x  key2 key1_y
# 0      d     3      c
# 1      c     1      d
# 2      B     8      B
#   key1  key2_x  key2_y
# 0    B       8       8
# 1    a       6       2
# 2    c       1       3
# 3    d       3       1
參數sort演示

pandas自帶的排序方法df.sort_index()、df.sort_values('column')

 

suffixes:如果兩者相同的column未被指定為參考列,那么結果中這兩個相同的column名稱會被加上后綴,默認為左右分別為_x和_y

df1 = pd.DataFrame({'key1':['a','b','c','d'],'key2':['e','f','g','h']},index=['k','l','m','n',])
df2 = pd.DataFrame({'key1':['a','B','c','d'],'key2':['e','f','g','H']},index = ['p','q','u','v'])
print(df1)
print(df2)
print(pd.merge(df1,df2,on='key1'))
print(pd.merge(df1,df2,on='key2',suffixes=('_df1','_df2')))
#   key1 key2_x key2_y
# 0    a      e      e
# 1    c      g      g
# 2    d      h      H
#   key1_df1 key2 key1_df2
# 0        a    e        a
# 1        b    f        B
# 2        c    g        c
參數suffixed演示

 

二、join

join是默認按照index、以left方式實現兩個DataFrame的合並,即默認用法相當於merge的pd.merge(df1,df2,how = 'left',left_index =  True,right_index = True),缺失值默認為NaN

df1.join(df2, on=None, how='left', lsuffix='', rsuffix='',sort=False)

由於join的lsuffix和rsuffix默認值為空,因此如果兩者有相同的column,一定要手動指定這兩個參數,否則會報錯。

 

join也可以通過on指定前面的DataFrame以column為參考與后面的index關聯實現合並,即相當於merge的pd.merge(df1,df2,how = 'left',left_on ='**',right_index = True)。

index重新生成為從0開始的整數。

df1 = pd.DataFrame({'key1':['a','b','c','d'],'key2':[1,2,3,4]})
df2 = pd.DataFrame({'key1':['a','B','c','d'],'key3':['e','f','g','H']})
print(df1)
print(df2)
print(df1.join(df2,on='key2',lsuffix='_df1',rsuffix='_df2'))
#   key1  key2
# 0    a     1
# 1    b     2
# 2    c     3
# 3    d     4
#   key1 key3
# 0    a    e
# 1    B    f
# 2    c    g
# 3    d    H
#   key1_df1  key2 key1_df2 key3
# 0        a     1        B    f
# 1        b     2        c    g
# 2        c     3        d    H
# 3        d     4      NaN  NaN
join演示

 

三、concat

上述merge和join都是指定了column或者index為參考對兩個DataFrame進行合並,concat是單純的對DataFrame進行堆疊,並且空值填充為NaN。

concat可一次實現對多個pandas對象的堆疊,默認是對所有列在垂直方向進行堆疊、index為原來各自的索引。

concat( [obj1, obj2, obj3], axis=0, join="outer", join_axes=None, ignore_index=False, keys=None, 
     levels=None, names=None, verify_integrity=False, sort=None, copy=True)

 

如果是在水平方向進行堆疊,需要指定axis=1,如果合並后有相同列名稱,可通過add_prefix或者add_suffix為其中一個添加名稱后綴。

s1 = pd.Series([1,2,3],index=['a','b','c'],name='s1')
s2 = pd.Series([3,4,'w'],index=['c','x','y'],name='s2')
print(s1)
print(s2)
print(pd.concat([s1,s2]))
print(pd.concat([s1,s2],axis=1,sort=False))
# a    1
# b    2
# c    3
# Name: s1, dtype: int64
# c    3
# x    4
# y    w
# Name: s2, dtype: object
# a    1
# b    2
# c    3
# c    3
# x    4
# y    w
# dtype: object
#     s1   s2
# a  1.0  NaN
# b  2.0  NaN
# c  3.0    3
# x  NaN    4
# y  NaN    w
參數axis演示

 

join表示堆疊方式,默認為outer,只有outer和inner方式,inner表示只對相同列進行堆疊。

s1 = pd.DataFrame([[1,2,3],[4,5,6]],columns=['a','b','c'])
s2 = pd.DataFrame([[3,4,'w'],[5,6,'x']],columns=['a','b','d'])
print(s1)
print(s2)
print(pd.concat([s1,s2]))
print(pd.concat([s1,s2],join="inner"))
#    a  b  c
# 0  1  2  3
# 1  4  5  6
#    a  b  d
# 0  3  4  w
# 1  5  6  x
#    a  b    c    d
# 0  1  2  3.0  NaN
# 1  4  5  6.0  NaN
# 0  3  4  NaN    w
# 1  5  6  NaN    x
#    a  b
# 0  1  2
# 1  4  5
# 0  3  4
# 1  5  6
參數join演示

 

ignore_index表示是否保留原對象的index,默認保留,True表示結果的index為從0開始的整數。

s1 = pd.Series([1,2,3],index=['a','b','c'],name='s1')
s2 = pd.Series([3,4,'w'],index=['c','x','y'],name='s2')
print(pd.concat([s1,s2]))
print(pd.concat([s1,s2],ignore_index=True))
# a    1
# b    2
# c    3
# c    3
# x    4
# y    w
# dtype: object
# 0    1
# 1    2
# 2    3
# 3    3
# 4    4
# 5    w
# dtype: object
參數ignore_index演示

 

join_axes指定結果顯示的行索引

s1 = pd.Series([1,2,3],index=['a','b','c'],name='s1')
s2 = pd.Series([3,4,'w'],index=['c','x','y'],name='s2')
print(pd.concat([s1,s2],axis=1))
print(pd.concat([s1,s2],axis=1,join_axes=[['a','c']]))
#     s1   s2
# a  1.0  NaN
# b  2.0  NaN
# c  3.0    3
# x  NaN    4
# y  NaN    w
#    s1   s2
# a   1  NaN
# c   3    3
參數join_axes演示

 

對於Seris來說,默認按照豎直方向堆疊,如果再指定keys,則會形成一個層次索引。

如果在設置axis=1的情況下即按照水平方向進行堆疊,再指定keys,則keys的值會成為column。

s1 = pd.Series([1,2,3],index=['a','b','c'],name='s1')
s2 = pd.Series([3,4,'w'],index=['c','x','y'],name='s2')
print(pd.concat([s1,s2]))   #豎直方向堆疊
print(pd.concat([s1,s2],keys=['s1','s2']))   #豎直方向堆疊,並形成一個層次索引
print(pd.concat([s1,s2],axis=1,keys=['s1','s2']))   #水平方向堆疊,keys的值為column
# a    1
# b    2
# c    3
# c    3
# x    4
# y    w
# dtype: object
# s1  a    1
#     b    2
#     c    3
# s2  c    3
#     x    4
#     y    w
# dtype: object
#     s1   s2
# a  1.0  NaN
# b  2.0  NaN
# c  3.0    3
# x  NaN    4
# y  NaN    w
參數keys演示

 

四、替換空值combine_first

在相同index和column的位置,用一個對象的值去替換另一個對象的空值NaN。

df1.combine_forst(df2),如果df2有不在df1中的index和column,直接追加上去。

df1 = pd.DataFrame([[1,np.nan,3],[np.nan,5,6]],columns=['a','b','c'])
df2 = pd.DataFrame([[3,4,'w'],[5,6,'x'],[7,8,9]],columns=['a','b','d'])
print(df1)
print(df2)
print(df1.combine_first(df2))  #對於index為0和1,在對應column位置使用df2的值替換df1的空值
#df2中的index=2和column='d'不在df1中,結果保留這一行和這里一列,
#      a    b  c
# 0  1.0  NaN  3
# 1  NaN  5.0  6
#    a  b  d
# 0  3  4  w
# 1  5  6  x
# 2  7  8  9
#      a    b    c  d
# 0  1.0  4.0  3.0  w
# 1  5.0  5.0  6.0  x
# 2  7.0  8.0  NaN  9
combine_first演示

 

五、更新update

在相同index和column的位置,使用一個對象的值去更新原對象的值,該方法沒有返回值,直接修改原對象。

df1.update(df2),更新df1,結果只包含原對象的行和列。

df1 = pd.DataFrame([[1,np.nan,3],[np.nan,5,6]],columns=['a','b','c'])
df2 = pd.DataFrame([[3,4,'w'],[5,6,'x'],[7,8,9]],columns=['a','b','d'])
df1.update(df2)  #沒有返回值,直接打印結果為none,且df2中的第3行和d列不追加到df1
print(df1)   
#      a    b  c
# 0  3.0  4.0  3
# 1  5.0  6.0  6
update演示

 

六、去重duplicate與drop_duplicates

duplicate()結果是一個值為布爾的Seris,通過obj[ df.duplicated()==False ]來取出Seris和DataFrame中的重復值、行,新結果的index為False對應的索引。

對於Seris,從第一個值開始判斷,如果元素第一次出現,則duplicate后的值為True,否則為False

對應於DataFrame,從第一行開始判斷,如果行的內容第一次出現(要求行內元素順序一致),則duplicate后的值為True,否則為False。如

s = pd.Series([1,2,2,1,3,3])
print(s.duplicated())
print(s[s.duplicated()==False])
print('----------------')
df = pd.DataFrame([[1,2,3],[4,5,6],[1,3,2],[4,5,6],[7,8,9]])
print(df.duplicated())   #[1,2,3]和[1,3,2]不重復
print(df[df.duplicated()==False])
# 0    False
# 1    False
# 2     True
# 3     True
# 4    False
# 5     True
# dtype: bool
# 0    1
# 1    2
# 4    3
# dtype: int64
# ----------------
# 0    False
# 1    False
# 2    False
# 3     True
# 4    False
# dtype: bool
#    0  1  2
# 0  1  2  3
# 1  4  5  6
# 2  1  3  2
# 4  7  8  9
duplicated去重

 

drop_duplicates( )刪除重復的元素,默認生成新的結果不修改原對象,如果添加參數inplace=True則直接修改原對象。新結果的index為元素第一次出現時對應的索引

s = pd.Series([1,2,2,1,3,3])
print(s.drop_duplicates())
df = pd.DataFrame([[1,2,3],[4,5,6],[1,3,2],[4,5,6],[7,8,9]])
df.drop_duplicates(inplace=True)
print(df)
# 0    1
# 1    2
# 4    3
# dtype: int64
#    0  1  2
# 0  1  2  3
# 1  4  5  6
# 2  1  3  2
# 4  7  8  9
drop_duplicates去重

 

七、替換replace

replace('原元素','新元素')將原元素替換成新元素

如果要同時替換多個元素,用列表表示即可;如果要將不同的元素替換成不同的內容,使用字典。

s = pd.Series(list('abcafc'))
print(s.replace('a','A'))  #將每個a替換成A
print(s.replace(['a','b'],'W'))   #將所有a、b替換成W
print(s.replace({'a':'A','f':'F'}))   #將a替換成A,f替換成F

df = pd.DataFrame([[1,2,3],[4,5,6],[2,5,8]])
print(df.replace(2,'a'))   #將2替換成a
replace演示

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM