pandas合併拼接的三種方法-join()、merge()及concat()方法

1.join()方法

這個方法通常的使用方式爲caller.join(),其中caller爲DataFrame類型的數據。先來看join()方法中的參數,具體如下:

參數 參數說明
other 要與caller合併拼接的數據。該參數可以接收三種類型的數據分別爲:Series,DataFrame以及多個DataFrame組成的list。如果other爲Series時,該Series必須設置name屬性,在最終返回的DataFrame中,該name屬性的值將作爲column名出現。
on 可選參數。規定caller中的字段用來與other進行匹配連接。可以接收三種類型的變量:str,多個str組成的list,以及類array類型的數據。這裏指定的是caller中的column列名或者索引層級名,然後用column對應的數據或index與other的index進行對比。也就是說,other只能使用index與caller的index或caller進行相等性匹配。
how

共有四種匹配方式:left(默認)、right、outer、inner。具體這四種方式與SQL中同名的匹配方式相同。

lsuffix、rsuffix 這兩個參數主要用來對caller和other中的同名列進行改名。
sort 接收bool型參數,默認爲False。當爲False時,依據how參數對返回的DataFrame進行排序。當爲True時,依據連接字段的字典序進行排序。
import pandas as pd
import numpy as np
df1=pd.DataFrame({'Name':['July','Shiely','Lucy','Lily'],'Salary':[5000,6000,4000,6000]})
ser1=pd.Series(['US','CN','UK','UK'],index=['July','Shiely','Lucy','Lily'],name='Nation')
df2=pd.DataFrame({'Name':['July','Shiely','Lucy','Joy','Lily'],'Major':['CS','CS','Art','Art','Math']})
df3=pd.DataFrame({'Name':['July','Shiely','Lucy','Lily','Joy'],
                  'University':['Beking','Beking','Tsing','Tsing','Beking']})
r1=df1.join(ser1,how='inner',on='Name')#用df1.Name字段和Ser1.index匹配
r2=df1.set_index('Name').join(df2.set_index('Name'),how='inner',sort=True)
#這裏是將Name屬性都設爲df1和df2的索引然後再進行匹配連接的。這時候就不用寫on條件了,
#同時df1和df2中的Name順序不一致也可以正常處理。
#同時sort字段實現了按name的字典序重新排序
r3=df1.join([df2.set_index('Name'),df3.set_index('Name')],on='Name',how='outer')
#other爲多個DataFrame組成的列表時,只能實現index對index的匹配,這個時候不能設置on參數
#而且df2和df3中不能有相同的column

r1、r2、r3的運行結果分別爲:

import pandas as pd
import numpy as np
df1=pd.DataFrame({'No.':range(1000,1004),
                  'Name':['July','Shiely','Lucy','Lily'],
                  'Salary':[5000,6000,4000,6000]})
df2=pd.DataFrame({'No.':range(1000,1005),
                  'Postion':['Manger','BOSS','BOSS','Manger','Manger'],
                  'Name':['July','Shiely','Lucy','Lily','Joy'],
                  'Bounce':[3000,1000,1000,2000,5000]})
r4=df1.join(df2.set_index(['No.','Name']),on=['No.','Name'],how='inner')
#如果df2中的有多層索引時,需要都出現在on條件中才能正確進行匹配
r5=df1.join(df2,lsuffix='_left',how='inner')#如果沒有設置lsuffix或rsuffix則會報錯

r4、r5的代碼運行結果如下:

總結:

  • 首先,從join()的參數列表可以看出,join中沒有axis參數,所以該方法只能實現按行拼接。
  • 其次,該方法不僅能實現兩個DataFrame的合併,還可以實現單個DataFrame與單個Series,或與多個DataFrame的拼接。
  • 最後,該方法只能用caller的column或index與other的index進行匹配。

2.merge()方法

merge()(通常以left.merge(right)方式使用)方法和join()功能上有些類似,但merge()方法中caller可以和right中的任意index或column進行匹配。具體參數列表如下:

參數 參數說明
right DataFrame(到底能不能接收Series,還需要進一步確認)
how 共有四種匹配方式:left、right、outer、inner(默認)。與SQL中類似。
on 可以接收column或index名。出現在這個參數中column或index必須同時出現在left和righ中。如果爲None,則默認使用兩個DataFrame中共有的column進行匹配。
left_on、right_on 可以單獨制定left和right的匹配的column或index。當left和right中要匹配的字段名不相同時,則可以使用這兩個參數。這兩個參數都可以接收label、list或類array的變量。

left_index、right_idnex

bool型變量,默認爲False。分別使用left或right的index作爲連接匹配字段。
sort 與join()中的同名參數用法相同。
suffixes 類似join()中的lsuffix和rsuffix。可以接收tuple型變量。
copy 布爾型變量,默認爲True。當爲False時,如果可能則避免拷貝。(這個參數具體什麼作用,目前還不清楚。)
indicator bool型變量、str型變量。默認爲False。當爲True時,會在返回的DataFrame中增加一個名爲‘_merge’的列來表名每行數據的來源(共三種標記;left_only、right_only、both)。當接收str型變量時,將新增的該列名字改爲indicator指定的名字。
validate 可選變量。接收str型變量。對left和right做檢查,如果不符合指定的匹配類型,則直接報錯。可指定的檢查類型爲:one_to_one、one_to_many、many_to_one、many_to_many
import pandas as pd
import numpy as np
df1=pd.DataFrame({'Name':['July','Shiely','Lucy','Lily'],'Salary':[5000,6000,4000,6000]})
df2=pd.DataFrame({'Name':['July','Shiely','Lucy','Joy','Lily'],'Major':['CS','CS','Art','Art','Math']})
df3=pd.DataFrame({'Name':['July','Shiely','Lucy','Lily','Kate'],
                  'University':['Beking','Beking','Tsing','Tsing','SHU']})
df4=pd.DataFrame({'No.':range(1000,1004),
                  'Name':['July','Shiely','Lucy','Lily'],
                  'Salary':[5000,6000,4000,6000]})
df5=pd.DataFrame({'No.':range(1000,1005),
                  'Postion':['Manger','BOSS','BOSS','Manger','Manger'],
                  'Name':['July','Shiely','Lucy','Lily','Joy'],
                  'Bounce':[3000,1000,1000,2000,5000]})
r1=df1.merge(df2.set_index('Name'),left_on='Name',right_index=True)
#df1.merge(df2,on='Name')
r2=df2.merge(df3,how='outer',indicator='source',validate='one_to_one')
r3=df4.merge(df5,on='No.',suffixes=('_left','_right'))
r4=df1.set_index('Name').merge(df2.set_index('Name'),left_index=True,right_index=True)

r1、r2、r3、r4的運行結果分別如下:

總結:

  • merge()方法和join()方法實現的功能相似,都是按行拼接。但merge()的用法更靈活。不僅支持index-on-index和column-on-index,還支持column-on-column。

3.pd.concat()方法

參數 參數說明
objs 待合併的數據。可以接受Series、DataFrame、Panel對象組成的序列或映射型數據。如果objs中有爲None的對象,則默認直接刪除。(但如果objs中全爲None,則報錯)
axis 可取0或1(默認爲0)。指定objs的合併拼接方向。當爲0時,爲按列拼接。當axis=1時,則與join()、merge功能類似,此時依據index進行合併,即index相同的會合併到同一行去。
join 可以取inner和outer(默認值)。用來指定如何處理非axis指定的軸上的index
join_axes 可接收index對象組成的列表。
ignore_index 布爾型變量。默認爲False。當爲True時,會重新指定返回值的索引
keys 可接收序列型數據。構建層次索引的最外層。objs中的每一個元素對應一個keys中的一個元素。還需要說明的是:一旦設置了keys,其長度必須大於等於1。如果keys的長度<objs的長度時,以keys的長度爲準,剩下的objs不合並。如果keys的長度>objs的長度時,objs全部輸出。
levels 可以接收序列組成的list作爲參數。指定特定的層級構建複合索引。(這個參數到底怎麼用,還需要進一步研究)。
names 可接收list型變量。默認值爲None。用來指定層次索引的名字
verify_integrity bool型變量,默認爲False。主要是檢查新的合併的軸上是否有重複值。
sort 0.23.0版本之後的新增參數。
copy 與merge()中的同名參數作用相同。
import pandas as pd
se1=pd.Series(['July','Shiely','Lucy','Lily'])
se2=pd.Series([5000,6000,4000,6000],index=range(1000,1004))
r1=pd.concat({'name':se1,'salary':se2},axis=0,join='outer')
#se1和se2也可以放在list或tuple裏
r2=pd.concat({'name':se1,'salary':se2},axis=0,join='outer',ignore_index=True)
#使用dict進行數據傳輸的時候,字典的鍵會作爲外層索引的名字或列名
#所以這裏series.name可以爲None
#使用了ignore_index之後,會重新給返回結果設置索引
df1=pd.DataFrame({'Name':['July','Shiely','Lucy','Lily'],'Salary':[5000,6000,4000,6000]},index=range(1000,1004))
df2=pd.DataFrame({'Name':['July','Shiely','Lucy','Joy','Lily'],'Major':['CS','CS','Art','Art','Math']},
                index=range(1000,1005))
r3=pd.concat((df1,df2),axis=0,join='inner',sort=False)
#join作用,當axis=0時,則只保留兩個待合併元素中的相同column
#當axis=1時,則只保留兩個待合併元素中的相同index
r4=pd.concat((df1,df2),axis=1,join='inner',sort=False)
r5=pd.concat([df1,se1,se2,df2],axis=1,join='outer')
#pd.concat()支持同時合併多種類型的數據

r1、r2、r3、r4、r5的返回結果依次如下

import pandas as pd
df1=pd.DataFrame({'No.':range(1000,1004),
                  'Name':['July','Shiely','Lucy','Lily'],
                  'Salary':[5000,6000,4000,6000]})
df2=pd.DataFrame({'No.':range(1000,1005),
                  'Postion':['Manger','BOSS','BOSS','Manger','Manger'],
                  'Name':['July','Shiely','Lucy','Lily','Joy'],
                  'Bounce':[3000,1000,1000,2000,5000]})
r1=pd.concat([df1,df2],keys=['upper','down'],names=['1','2'])

總結:

  • 在使用方法上,join和merge都支持DataFrame.join()\merge()形式,但concat()方法不是DataFrame自帶的方法,所以只能通過pd.concat()方式來使用該方法。基於此,pd.concat()支持更多類型的數據合併。不僅支持DataFrame之間的合併,也支持Serie之間的合併。
  • 在axis=0軸上進行合併時,其功能類似於append。而當axis=1時,其功能類似於join或merge,但此時只能將index相同數據合併到同一行。若要依據其他column進行合併的話,則需要先將改列設爲index。

參考資

1.https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.join.html

2.https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.merge.html

3.https://pandas.pydata.org/pandas-docs/version/0.23.4/generated/pandas.concat.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章