首頁 >
熱門文章 >
大數(shù)據(jù)分析 > 大數(shù)據(jù)分析Pandas和Python如何合并數(shù)據(jù)表
大數(shù)據(jù)分析Pandas和Python如何合并數(shù)據(jù)表
時(shí)間:2020-09-29來源:m.5wd995.cn點(diǎn)擊量:次作者:Sissi
時(shí)間:2020-09-29點(diǎn)擊量:次作者:Sissi
你將很難找到不需要串聯(lián)的大數(shù)據(jù)分析項(xiàng)目(將多個(gè)數(shù)據(jù)源組合在一起)。通常,數(shù)據(jù)分析要求將新行添加到表中,在更復(fù)雜的情況下(在更復(fù)雜的情況下)拉出更多列,將不同的表合并到一個(gè)公共鍵上。所有這些技巧都可以輕松地放在口袋里,因此不同的數(shù)據(jù)源不會(huì)妨礙你的分析!
在此串聯(lián)教程中,我們將逐步介紹幾種使用熊貓組合數(shù)據(jù)的方法。它面向初學(xué)者到中級(jí),并且需要了解熊貓DataFrame的基礎(chǔ)知識(shí)。對(duì)SQL和關(guān)系數(shù)據(jù)庫的一些事先了解也將派上用場,但不是必需的。我們將分析四種國家的平均年度勞動(dòng)時(shí)間,并介紹四種不同的技術(shù)(連接,附加,合并和合并)。我們還將在每個(gè)步驟之后創(chuàng)建一個(gè)圖,以便我們直觀地了解每種數(shù)據(jù)組合技術(shù)所產(chǎn)生的不同結(jié)果。作為獎(jiǎng)勵(lì),你將在大數(shù)據(jù)分析Pandas和Python如何合并數(shù)據(jù)表中獲得有關(guān)全球勞動(dòng)力趨勢(shì)的見解以及可添加到你的投資組合中的漂亮圖表集!
我們將在經(jīng)濟(jì)合作與發(fā)展組織(OECD)中扮演宏觀經(jīng)濟(jì)分析師的角色。我們?cè)噲D回答的問題很簡單,但很有趣:哪個(gè)國家的公民投入了最長的工作時(shí)間,這些趨勢(shì)隨著時(shí)間的推移如何變化?不幸的是,經(jīng)合組織一直在分別收集不同大陸和不同時(shí)期的數(shù)據(jù)。我們的工作是首先將所有數(shù)據(jù)放在一個(gè)位置,以便我們進(jìn)行必要的分析。
訪問數(shù)據(jù)集
在此處下載教程數(shù)據(jù)文件
我們將使用來自O(shè)ECD就業(yè)和勞動(dòng)力市場統(tǒng)計(jì)數(shù)據(jù)庫的數(shù)據(jù),該數(shù)據(jù)庫提供了可追溯至1950年的大多數(shù)發(fā)達(dá)國家的平均年度勞動(dòng)小時(shí)數(shù)據(jù)。在大數(shù)據(jù)分析Pandas和Python如何合并數(shù)據(jù)表中,我將互換使用DataFrames和表格。我們將在Python 3中使用Jupyter Notebook(歡迎使用你希望使用的任何IDE(集成開發(fā)環(huán)境),但是在Jupyter中最容易遵循大數(shù)據(jù)分析Pandas和Python如何合并數(shù)據(jù)表)。啟動(dòng)后,讓我們導(dǎo)入pandas和matplotlib庫,然后使用%matplotlb inlineJupyter知道如何在筆記本單元格中顯示圖。如果我提到的任何工具聽起來都不熟悉,建議你參閱AAA教育入門指南。
接下來,我們將使用該pd.read_csv()函數(shù)打開前兩個(gè)數(shù)據(jù)文件。我們將通過傳遞參數(shù)指定將第一列用作行索引index_col=0。最后,我們將顯示初始表的外觀。
經(jīng)過一番觀察,我們發(fā)現(xiàn)行是國家,列是年,單元格值是每位員工的平均每年工作時(shí)間。盡管DataFrames輝煌,但乍一看仍然很難理解,因此我們將使用matplotlib的DataFrame.plot()方法為我們的年度勞動(dòng)趨勢(shì)創(chuàng)建折線圖,進(jìn)行一些繪圖。
哇,那不是我們想要的!默認(rèn)情況下,該DataFrame.plot()方法將行視為x軸標(biāo)簽,將單元格值視為y軸標(biāo)簽,將列視為線。此處的快速解決方案是使用DataFrame.transpose()方法在DataFrame上旋轉(zhuǎn)軸。為了使可視化效果更加出色,我們將title='string'在plot方法中使用參數(shù)添加標(biāo)題。我們可以將這些方法鏈接在一起,然后用于plt.show()整齊地顯示我們的折線圖,而繪圖上方?jīng)]有matplotlib文本行。
連接美洲數(shù)據(jù)
看起來我們?cè)趎orth_americaDataFrame中有三個(gè)國家,在DataFrame中有一個(gè)國家south_america。由于這些是在兩個(gè)單獨(dú)的圖中,因此很難比較南美和北美的平均勞動(dòng)時(shí)間。如果我們能夠?qū)⑺袊?地區(qū)納入同一個(gè)數(shù)據(jù)框,則進(jìn)行此活動(dòng)會(huì)容易得多。
對(duì)于需要添加相同長度的行或列的簡單操作,此pd.concat()功能非常理想。我們要做的就是按照我們希望它們串聯(lián)的順序傳遞一個(gè)DataFrame對(duì)象列表。
a)軸:我們將沿著行(0)還是沿列(1)串聯(lián)
b)join:可以設(shè)置為內(nèi)部,外部,左側(cè)或右側(cè);大數(shù)據(jù)分析Pandas和Python如何合并數(shù)據(jù)表后面將更詳細(xì)地解釋
c)ignore_index:是否應(yīng)保留原始行標(biāo)簽
在我們的例子中,我們可以保留所有默認(rèn)參數(shù)的原樣,而只需傳入我們north_america和south_americaDataFrames。
這看起來是一個(gè)不錯(cuò)的開始,但是我們希望我們的數(shù)據(jù)盡可能的新。以后幾年要求提供這四個(gè)國家/地區(qū)的數(shù)據(jù)后,數(shù)據(jù)收集團(tuán)隊(duì)從2011年到2015年每年通過單獨(dú)的CSV文件向我們發(fā)送以下信息:
[americas_2011.csv , americas_2012.csv, americas_2014.csv, americas_2015.csv]
讓我們使用一個(gè)for循環(huán)以及該string.format()方法自動(dòng)執(zhí)行該過程的方法來加載新數(shù)據(jù)。我們將把我們之前的americasDataFrame放在一個(gè)名為的列表中,americas_dfs并將每個(gè)新DataFrame追加到該列表中。最后,我們將americas_2011使用列表索引顯示DataFrame。
你可能會(huì)注意到的一件事是,americas_2011我們剛打印的DataFrame中的行與DataFrame的順序americas不同(熊貓自動(dòng)將它們按字母順序排列)。幸運(yùn)的是,該pd.concat()函數(shù)將數(shù)據(jù)連接到索引標(biāo)簽(在我們的情況下為國家)中,而不是順序中,因此在連接期間不會(huì)出現(xiàn)問題。如果我們想按當(dāng)前順序?qū)⑿羞B接起來,則可以傳遞參數(shù)ignore_index=True。這將導(dǎo)致為索引分配整數(shù)序列。同樣重要的是要記住,我們必須按照希望將其串聯(lián)的順序創(chuàng)建DataFrame列表,否則我們的年份將不按時(shí)間順序排列。
我們不能使用與pd.concat()上次完全相同的功能,因?yàn)楝F(xiàn)在我們要添加列而不是行。這是軸起作用的地方。默認(rèn)情況下,參數(shù)設(shè)置為axis=0,這意味著我們正在串聯(lián)行。這次,我們將需要傳遞axis=1以指示我們要串聯(lián)列。請(qǐng)記住,這僅在所有表都具有相同的高度(行數(shù))的情況下起作用。
堆棧溢出
沿軸1連接時(shí)要記住的一個(gè)警告是行索引的標(biāo)題“國家”將被刪除。這是因?yàn)閜andas不確定該標(biāo)題是否適用于已添加的新行標(biāo)簽。我們可以通過分配DataFrame.index.names屬性輕松地解決此問題。然后,讓我們作另一個(gè)圖以了解我們的位置。
追加其他大洲的數(shù)據(jù)
既然我們已經(jīng)全面了解了美洲,那么我們想看看它與世界其他地區(qū)的比較。數(shù)據(jù)收集團(tuán)隊(duì)已為2000年至2015年為亞洲,歐洲和南太平洋提供了CSV文件。讓我們加載這些文件并進(jìn)行預(yù)覽。由于europe是一張高得多的桌子,我們將利用該DataFrame.head()方法通過僅顯示前5行來節(jié)省空間。
當(dāng)你只想添加稱為DataFrame.append()方法的新行時(shí),Pandas有一個(gè)快捷方式。語法略有不同–因?yàn)樗荄ataFrame方法,所以我們將使用點(diǎn)表示法在americas對(duì)象上調(diào)用它,然后將新對(duì)象作為參數(shù)傳遞。
看起來這些新的DataFrames已全部用了16年。如果我們嘗試追加的數(shù)據(jù)中缺少任何列,則將導(dǎo)致這些行NaN的單元格中的值落在缺少的年列之下。讓我們運(yùn)行append方法,并驗(yàn)證通過print正確地附加了所有國家DataFrame.index。然后,我們可以繪制折線圖以查看新附加數(shù)據(jù)的外觀。
自定義可視化
具有所有36個(gè)國家/地區(qū)的新DataFrame很棒,但是圣潔的行為確實(shí)使我們的計(jì)劃變得混亂!在繼續(xù)之前,請(qǐng)查看你是否可以發(fā)現(xiàn)我們的可視化存在的三個(gè)問題。
首先,我們要使圖更大,以便可以以更高的保真度看到所有這些新數(shù)據(jù)點(diǎn)。如果我們傳遞figsize=(10,10)參數(shù),這是一個(gè)非常容易的解決方案,元組指定了繪圖圖的尺寸。你可能還已經(jīng)注意到,有36條線代表我們所有不同的國家,但是顏色在重復(fù)。這是因?yàn)槟J(rèn)的顏色圖僅包含10種不同的顏色,但是我們將需要更多的顏色。我查看了matplotlib colormaps文檔,并決定使用彩虹圖,可以將其作為傳遞colormap='rainbow'。由于我們要放大圖表,因此我也想使用較粗的線,所以我要設(shè)置linewidth=2。
最后,我們將解決圖例中重疊的圖例。這可以通過plt.legend()功能來完成。我們將傳入loc='right'以指示我們想要圖右側(cè)的圖例框。你可以對(duì)其進(jìn)行測(cè)試,并發(fā)現(xiàn)它與圖的邊界不完全對(duì)齊。我們可以對(duì)bbox_to_anchor=(1.3,0.5)參數(shù)進(jìn)行一些微調(diào)。我們傳入的元組是圖例框相對(duì)于圖的位置坐標(biāo)。我一直在研究這些值,直到找到一個(gè)可以排列的值,但是如果你喜歡不同的美學(xué),可以隨時(shí)修改這四個(gè)參數(shù)中的任何一個(gè)。
連接入門
對(duì)于那些在SQL之類的關(guān)系數(shù)據(jù)庫中進(jìn)行聯(lián)接的經(jīng)驗(yàn)豐富的人,這里有一些好消息:pandas提供了高性能的內(nèi)存中合并和聯(lián)接選項(xiàng)。當(dāng)我們需要組合非常大的DataFrame時(shí),聯(lián)接是快速執(zhí)行這些操作的有力方法。
需要牢記的幾個(gè)重要事項(xiàng):一次只能在兩個(gè)DataFrame上進(jìn)行連接,分別表示為左表和右表。該鍵是普通列,這兩個(gè)DataFrames將加入的。最好使用在整個(gè)列中具有唯一值的鍵,以避免行值的意外復(fù)制。
有四種處理聯(lián)接的基本方法(內(nèi)部,左側(cè),右側(cè)和外部),具體取決于哪些行必須保留其數(shù)據(jù)。下面的維恩圖將幫助你直觀地理解這些連接??紤]將藍(lán)色區(qū)域作為鍵列的一部分,它將保留在最終表中。
一個(gè)內(nèi)連接是最簡單的聯(lián)接,這樣只會(huì)保留其中兩個(gè)表共用一個(gè)鍵值的行。
一個(gè)左連接不斷出現(xiàn)在主(左)表中的所有行,右表僅將對(duì)把它分享與左的一個(gè)關(guān)鍵值的行串連。NaN將為沒有匹配鍵值的單元格填充值。
一個(gè)右連接是同一個(gè)概念作為左加入,但保持在右表中出現(xiàn)的所有行。所得的DataFrameNaN在左側(cè)將具有任何可能的值。
最后,完全外部NaN聯(lián)接保留了兩個(gè)表中都出現(xiàn)的所有行,并且值可以顯示在結(jié)果DataFrame的任一側(cè)。
合并歷史勞工數(shù)據(jù)
很高興能夠看到自2000年以來的工時(shí)變化,但是為了看到真實(shí)的趨勢(shì),我們希望能夠看到盡可能多的歷史數(shù)據(jù)。數(shù)據(jù)收集團(tuán)隊(duì)非常友好,可以發(fā)送從1950年到2000年的數(shù)據(jù),讓我們將其加載并進(jìn)行查看。
你會(huì)注意到其中有很多NaN價(jià)值,尤其是在早期。這僅意味著在較早的年份中沒有收集到這些國家的數(shù)據(jù)。在這些單元格中放入0會(huì)產(chǎn)生誤導(dǎo),因?yàn)檫@意味著該年沒有人花任何時(shí)間工作!而是NaN代表一個(gè)空值,表示“不是數(shù)字”。具有空值不會(huì)影響我們的DataFrame合并,因?yàn)槲覀儗⑹褂眯袠?biāo)簽(索引)作為鍵。
合并時(shí),請(qǐng)務(wù)必記住將從每個(gè)表保留哪些行。我不確定表的完整尺寸是多少,因此,除了顯示全部內(nèi)容之外,我們還可以查看感興趣的事實(shí)。讓我們打印DataFrame.shape()屬性以查看包含(總行,總列)的元組對(duì)于兩個(gè)表。
請(qǐng)注意,即使我們僅分析世界表中的36個(gè)國家,歷史表也有39行。通過適當(dāng)?shù)腄ataFrame合并,可以自動(dòng)處理掉多余的三行。我們將把它world作為主表,希望它在結(jié)果DataFrame的右側(cè),而歷史在左側(cè),因此年份(列)按時(shí)間順序排列。這兩個(gè)表中的列都是不同的,這意味著我們將必須找到要連接的鍵。在這種情況下,鍵將是行索引(國家/地區(qū))。
我們將要使用該pd.merge()函數(shù)進(jìn)行正確的聯(lián)接,并使用索引作為聯(lián)接的鍵。
使用此函數(shù)時(shí),前兩個(gè)參數(shù)將始終分別為左和右DataFrame。然后,我們要設(shè)置left_index=True并right_index=True指定索引將是我們的鍵值,因此我們可以將國家/地區(qū)保留為行標(biāo)簽(否則熊貓會(huì)將行索引更改為整數(shù)序列。)最后,我們傳入how='right'以指示正確的加入。
正確的聯(lián)接將確保我們僅保留正確表中的36行,并丟棄歷史記錄表中多余的3行。讓我們打印生成的DataFrame的形狀并顯示頭部,以確保一切都正確。
更快的加入方式
現(xiàn)在,我們已經(jīng)完成了艱苦的工作,并從概念上理解了表合并,現(xiàn)在讓我們嘗試一種更優(yōu)雅的技術(shù)。熊貓有一個(gè)干凈的方法可以加入索引,這非常適合我們的情況。
該DataFrame.join()方法允許我們?cè)谧蟊砩鲜褂命c(diǎn)符號(hào),然后將右表how作為參數(shù)傳遞。這樣就無需像在上一個(gè)函數(shù)中那樣指定左右索引參數(shù)。如果為on=None,則連接鍵將為行索引。讓我們通過查看DataFrame頭來觀察空值如何影響我們的分析。
看起來很多行在DataFrame的左側(cè)都有空值,正如我們期望的那樣,使用右連接。在繪制最終的折線圖之前,最好按字母順序?qū)π羞M(jìn)行排序,以使圖例更易于讀者閱讀。可以使用DataFrame.sort_index()方法執(zhí)行。我們可以傳入?yún)?shù)inplace=True以避免重新分配world_historical變量。然后,只需重用我們最近的vizualization中的matplotlib代碼即可顯示我們最終排序的DataFrame。
放在一起(雙關(guān)語意)
哇,既然我們對(duì)半個(gè)多世紀(jì)以來的勞動(dòng)趨勢(shì)有了很大的了解,那么我們的可視化效果就令人印象深刻。成為80年代的工人肯定會(huì)筋疲力盡!
總結(jié)一下:
1)pd.concat() 功能:用途最廣,可用于沿任一軸組合多個(gè)DataFrame。
2)DataFrame.append() 方法:將行添加到DataFrame的快速方法,但不適用于添加列。
3)pd.merge() 函數(shù):當(dāng)我們有一個(gè)包含公用值的列(鍵)時(shí),非常適合將兩個(gè)DataFrame結(jié)合在一起。
4)DataFrame.join() 方法:連接兩個(gè)DataFrame的一種更快的方法,但是僅在索引標(biāo)簽上起作用,而不是在列上起作用。