拯救pandas計劃(14)——merge合并多個數(shù)據(jù)框
拯救pandas計劃(14)——merge合并多個數(shù)據(jù)框
最近發(fā)現(xiàn)周圍的很多小伙伴們都不太樂意使用pandas,轉(zhuǎn)而投向其他的數(shù)據(jù)操作庫,身為一個數(shù)據(jù)工作者,基本上是張口pandas,閉口pandas了,故而寫下此系列以讓更多的小伙伴們愛上pandas。
系列文章說明:
系列名(系列文章序號)——此次系列文章具體解決的需求
平臺:
windows 10 python 3.8 pandas >=1.2.4
/ 數(shù)據(jù)需求
對以下三組數(shù)據(jù)框,按A列進(jìn)行橫向合并,如同SQL里join表操作,最后生成的列名有A, num, label, count四列。

/ 需求拆解
數(shù)據(jù)合并在python中并不少見,例如列表的append,extend,+都可以擴(kuò)增列表元素,字典的update也可以根據(jù)另一個字典來更新當(dāng)前字典的元素。
在pandas里也不例外,有許多合并的函數(shù)方法,如concat,join,merge。
concat不會要求合并的數(shù)據(jù)框形式是否一致,只要符合合并的類型就能夠進(jìn)行合并。
join需要設(shè)定合并數(shù)據(jù)的基準(zhǔn)列,在該例中為A列,且需要將其設(shè)置為索引方可進(jìn)行合并,在pandas中并不能直接使用join方法,在DataFrame()類下才能使用。
merge可以合并左表數(shù)據(jù)框和右表數(shù)據(jù)框,從描述來看merge只能兩兩合并,其合并的方式和join類型,在參數(shù)設(shè)置上有些許不同,不需要將基準(zhǔn)列設(shè)置在索引上,也可以不設(shè)置基準(zhǔn)列,會自動尋找兩表之間相同的列名作為基準(zhǔn)列進(jìn)行合并。
/ 需求處理
數(shù)據(jù)框的上下左右合并,使用concat設(shè)置對應(yīng)的axis的參數(shù)就可以輕松解決。
若要滿足需求來合并幾個數(shù)據(jù)框,concat就需要靠邊了。先使用比較易理解的join,在sql語句中連接兩個表是非常常見的。
join
因?yàn)閜andas下不能直接調(diào)用join,在a數(shù)據(jù)框后連接其他數(shù)據(jù)框。
#?以a數(shù)據(jù)框作為基礎(chǔ)表,連接另外兩個數(shù)據(jù)框
#?上文提到,需要將基準(zhǔn)列設(shè)置為索引才能連接??
#?on設(shè)置連接的列名,此時已處于索引上,當(dāng)為多個值時,被連接對象需要含多級索引??
#?how連接方式,默認(rèn)為`left`,左連接,這里設(shè)置為`outer`,外連接方式
a.set_index('A').join(b.set_index('A'),?on='A',?how='outer')

已經(jīng)按A列各元素合并了其他列,若對應(yīng)列下沒有用nan填充,可以看到A列仍為列名稱。
嘗試合并多表:
#?這里設(shè)置on參數(shù)會報錯,原因未去探究
a.set_index('A').join([b.set_index('A'),?c.set_index('A')],?how='outer')

能夠完成需求,此時注意到A列數(shù)據(jù)已作為索引列出現(xiàn),在合并兩個數(shù)據(jù)框時,取消on參數(shù)的設(shè)置,同樣會使A列作為索引列。??
(手動水?。涸瓌?chuàng)CSDN宿者朽命,https://blog.csdn.net/weixin_46281427?spm=1011.2124.3001.5343 ,公眾號A11Dot派)
merge
在前文中提到,merge只能對兩個數(shù)據(jù)框進(jìn)行操作,在pandas下可以直接使用merge方法,也可以在數(shù)據(jù)框下調(diào)用方法,參數(shù)無區(qū)別。
#?pd.merge??
pd.merge(a,?b,?how='outer',?on='A')??
#?a.merge(b)?-?1??
a.merge(b,?how='outer',?on='A')??
#?a.merge(b)?-?2??
a.merge(b,?how='outer')



三種形式生成的結(jié)果是一樣的,而需要連接第三個表只需要將前兩個的連接的結(jié)果與第三個表相連接就行。
a.merge(b,?how='outer',?on='A').merge(c,?how='outer',?on='A')

當(dāng)需要連接的數(shù)據(jù)框比較多時,一個一個寫就比較費(fèi)力,可以使用for循環(huán)來完成這一目的,在itertools模塊下有一個累加迭代器可以替換for循環(huán)。為了更符合實(shí)際操作,將數(shù)據(jù)框放置到一個列表容器里。
from?itertools?import?accumulate
import?pandas?as?pd
data_list?=?[a,?b,?c]
res_iter?=?accumulate(data_list,?lambda?x,?y:?x.merge(y,?how='outer',?on='A'))
#?res_iter為迭代器,逐個運(yùn)行返回最后一個結(jié)果
for?i?in?range(len(data_list)):
????result?=?next(res_iter)
result
accumulate迭代器將傳入的可迭代對象參數(shù)(第一個參數(shù)),以func函數(shù)(第二個參數(shù))需要的參數(shù)獲取所需數(shù)量的參數(shù)個數(shù)進(jìn)行操作計算,將每次運(yùn)行的結(jié)果返回至迭代器中,之后的計算中,根據(jù)上一次計算的結(jié)果作為x參數(shù),當(dāng)前入?yún)⒆鳛閥參數(shù)依次迭代返回,迭代器結(jié)果的最后一個元素就是想要得到的目標(biāo)值。(此處有改動,請閱讀原文)

/ 總結(jié)
正如古話說,條條道路通羅馬。其實(shí)不用在意方法的多樣性,找到符合自己的解決方式就行了,使用的方法越高級,在當(dāng)時學(xué)習(xí)中理解難度就會越高,有朝一日能夠理解高級方法的含義時再回來使用它也是可以的。
閑日賞花兩支半,嘆有青空風(fēng)箏留。
于二零二二年四月二十日作
