1. 程式人生 > >小白學 Python 資料分析(13):Pandas (十二)資料表拼接

小白學 Python 資料分析(13):Pandas (十二)資料表拼接

![](https://cdn.geekdigging.com/python/spider-blog/Python_logo.jpg) > 人生苦短,我用 Python 前文傳送門: [小白學 Python 資料分析(1):資料分析基礎](https://www.geekdigging.com/2020/01/19/6719980708/) [小白學 Python 資料分析(2):Pandas (一)概述](https://www.geekdigging.com/2020/01/20/6718497214/) [小白學 Python 資料分析(3):Pandas (二)資料結構 Series](https://www.geekdigging.com/2020/02/04/3234667780/) [小白學 Python 資料分析(4):Pandas (三)資料結構 DataFrame](https://www.geekdigging.com/2020/02/05/9920298470/) [小白學 Python 資料分析(5):Pandas (四)基礎操作(1)檢視資料](https://www.geekdigging.com/2020/02/16/6852411690/) [小白學 Python 資料分析(6):Pandas (五)基礎操作(2)資料選擇](https://www.geekdigging.com/2020/02/20/6566891797/) [小白學 Python 資料分析(7):Pandas (六)資料匯入](https://www.geekdigging.com/2020/02/23/7355903936/) [小白學 Python 資料分析(8):Pandas (七)資料預處理](https://www.geekdigging.com/2020/02/25/9013297409/) [小白學 Python 資料分析(9):Pandas (八)資料預處理(2)](https://www.geekdigging.com/2020/02/27/2857868620/) [小白學 Python 資料分析(10):Pandas (九)資料運算](https://www.geekdigging.com/2020/02/29/5808964196/) [小白學 Python 資料分析(11):Pandas (十)資料分組](https://www.geekdigging.com/2020/03/03/5975552137/) [小白學 Python 資料分析(12):Pandas (十一)資料透視表(pivot_table)](https://www.geekdigging.com/2020/03/04/8327177610/) ## 引言 說到資料表拼接,就不得不提一下 SQL ,對於熟悉 SQL 的同學來講,這並不是一個難以理解的概念,資料表之間的關係可以分為以下這三種: ### 一對一 兩個表之間的公共列是一對一的。 這裡的示例我們就不用圖片了,直接使用程式碼來做展示,原因嘛就是小編懶的畫了: ```python import pandas as pd df1 = pd.read_excel("table_join_exp.xlsx", sheet_name='Sheet1') print(df1) # 輸出內容 編號 姓名 分數 0 100 小明 96 1 200 小紅 48 2 300 小王 72 3 400 小剛 72 df2 = pd.read_excel("table_join_exp.xlsx", sheet_name='Sheet2') print(df2) # 輸出內容 編號 班級 0 100 1 1 200 2 2 300 3 3 400 4 ``` 這裡可以很直觀的看到,這兩個表的編號是公共列,並且唯一對應。 如果我們要講這兩個表進行連線操作,需要使用 `merge()` 方法: ```python print(pd.merge(df1, df2)) # 輸出內容 編號 姓名 分數 班級 0 100 小明 96 1 1 200 小紅 48 2 2 300 小王 72 3 3 400 小剛 72 4 ``` 在我們使用 `merge()` 方法的時候, `merge()` 方法會自動尋找兩個表中的公共列,並且自動的進行對應操作。 ### 一對多 兩個表之間的公共列不是一對一的,而是其中一個表的公共列是唯一的,另一個表的公共列則會有重複的資料。 ```python import pandas as pd df1 = pd.read_excel("table_join_exp.xlsx", sheet_name='Sheet1') print(df1) # 輸出內容 編號 姓名 分數 0 100 小明 96 1 200 小紅 48 2 300 小王 72 3 400 小剛 72 df3 = pd.read_excel("table_join_exp.xlsx", sheet_name='Sheet3') print(df3) # 輸出內容 編號 分數 0 100 101 1 100 102 2 100 103 3 100 104 4 200 201 5 200 202 6 300 301 7 400 401 ``` 從上面這兩個 df 中可以看到, df1 中的編號在 df3 中會對應多條資料,我們在對這兩個 df 進行連線操作的時候,需要使用屬性 `on` 指明判斷的條件: ```python print(pd.merge(df1, df3, on='編號')) # 輸出內容 編號 姓名 分數_x 分數_y 0 100 小明 96 101 1 100 小明 96 102 2 100 小明 96 103 3 100 小明 96 104 4 200 小紅 48 201 5 200 小紅 48 202 6 300 小王 72 301 7 400 小剛 72 401 ``` ### 多對多 兩個表之間的公共列都是會有重複資料的,相當於是多個一對多。 注意理解多個一對多,這裡的邏輯稍微有點繞,小編在第一次接觸 SQL 的時候實際上是無法理解的。 我們這裡新建一個 df4 ,新增一個編號為 100 的小黑,還是通過編號對 df4 和 df3 進行連線操作: ```python df4 = pd.read_excel("table_join_exp.xlsx", sheet_name='Sheet4') print(df4) # 輸出結果 編號 姓名 分數 0 100 小明 96 1 100 小黑 100 2 200 小紅 48 3 300 小王 72 4 400 小剛 72 print(pd.merge(df4, df3, on='編號')) 編號 姓名 分數_x 分數_y 0 100 小明 96 101 1 100 小明 96 102 2 100 小明 96 103 3 100 小明 96 104 4 100 小黑 100 101 5 100 小黑 100 102 6 100 小黑 100 103 7 100 小黑 100 104 8 200 小紅 48 201 9 200 小紅 48 202 10 300 小王 72 301 11 400 小剛 72 401 ``` ## 連線方式 學過 SQL 的同學都知道, SQL 中連線分為內連線、左連線、右連線和外連線,同樣在 Pandas 也是一樣的。 ### 內連線 內連線就是取兩個表中公共的部分,我們重新建立一個 df5 ,在 df5 中只有編號 100 和 200 能和前面的資料保持一致: ```python df5 = pd.read_excel("table_join_exp.xlsx", sheet_name='Sheet5') print(df5) # 輸出結果 編號 姓名 分數 0 100 小明 96 1 100 小黑 100 2 200 小紅 48 3 600 想不出來叫啥了1 600 4 700 想不出來叫啥了2 700 # 內連線 print(pd.merge(df5, df3, on='編號', how='inner')) # 輸出結果 編號 姓名 分數_x 分數_y 0 100 小明 96 101 1 100 小明 96 102 2 100 小明 96 103 3 100 小明 96 104 4 100 小黑 100 101 5 100 小黑 100 102 6 100 小黑 100 103 7 100 小黑 100 104 8 200 小紅 48 201 9 200 小紅 48 202 ``` 這裡 `how` 屬性是用來指定連線型別的。 ### 左連線 左連線就是已左表為基礎,右表像左表上拼資料: ```python # 左連線 print(pd.merge(df5, df3, on='編號', how='left')) # 輸出結果 編號 姓名 分數_x 分數_y 0 100 小明 96 101.0 1 100 小明 96 102.0 2 100 小明 96 103.0 3 100 小明 96 104.0 4 100 小黑 100 101.0 5 100 小黑 100 102.0 6 100 小黑 100 103.0 7 100 小黑 100 104.0 8 200 小紅 48 201.0 9 200 小紅 48 202.0 10 600 想不出來叫啥了1 600 NaN 11 700 想不出來叫啥了2 700 NaN ``` 可以看到,在 df5 中,編號 600 和 700 的兩條資料在 df3 中沒有,所以 分數_y 的值為 NaN 。 ### 右連線 右連線正好和上面的左連線相反,已右表為基礎,左表往右表上拼資料: ```python # 右連線 print(pd.merge(df5, df3, on='編號', how='right')) # 輸出結果 編號 姓名 分數_x 分數_y 0 100 小明 96.0 101 1 100 小黑 100.0 101 2 100 小明 96.0 102 3 100 小黑 100.0 102 4 100 小明 96.0 103 5 100 小黑 100.0 103 6 100 小明 96.0 104 7 100 小黑 100.0 104 8 200 小紅 48.0 201 9 200 小紅 48.0 202 10 300 NaN NaN 301 11 400 NaN NaN 401 ``` ### 外連線 外連線就是兩個表的並集: ```python # 外連線 print(pd.merge(df5, df3, on='編號', how='outer')) # 輸出結果 編號 姓名 分數_x 分數_y 0 100 小明 96.0 101.0 1 100 小明 96.0 102.0 2 100 小明 96.0 103.0 3 100 小明 96.0 104.0 4 100 小黑 100.0 101.0 5 100 小黑 100.0 102.0 6 100 小黑 100.0 103.0 7 100 小黑 100.0 104.0 8 200 小紅 48.0 201.0 9 200 小紅 48.0 202.0 10 600 想不出來叫啥了1 600.0 NaN 11 700 想不出來叫啥了2 700.0 NaN 12 300 NaN NaN 301.0 13 400 NaN NaN 401.0 ``` ## 縱向拼接 顧名思義,縱向拼接就是在縱向上對兩個表進行拼接,當然這需要兩個表具有相同的結構,前面我們介紹的拼接方式都在橫向上進行拼接。 這裡我們再加入一個 df6 ,使用 df5 和 df6 演示縱向拼接,在 Pandas 中使用縱向拼接使用的方法是 `concat()` : ```python df6 = pd.read_excel("table_join_exp.xlsx", sheet_name='Sheet6') print(df6) # 輸出結果 編號 姓名 分數 0 800 起個名字好難啊 100 1 900 起個名字真的難 200 # 縱向拼接 print(pd.concat([df5, df6])) # 輸出結果 編號 姓名 分數 0 100 小明 96 1 100 小黑 100 2 200 小紅 48 3 600 想不出來叫啥了1 600 4 700 想不出來叫啥了2 700 0 800 起個名字好難啊 100 1 900 起個名字真的難 200 ``` 當我們使用 `concat()` 以後,發現索引還是保留了原有的索引,看著很不舒服,這時我們可以設定引數 `ignore_index` ,讓其不在保留原有索引,而是生成新的索引: ```python print(pd.concat([df5, df6], ignore_index=True)) # 輸出結果 編號 姓名 分數 0 100 小明 96 1 100 小黑 100 2 200 小紅 48 3 600 想不出來叫啥了1 600 4 700 想不出來叫啥了2 700 5 800 起個名字好難啊 100 6 900 起個名字真的難 200 ``` 本篇的分享到這裡就算結束,如果有 SQL 基礎的同學看起來應該毫無壓力,沒有基礎的同學推薦自己動手試一下,很多看著不是很理解的東西一動手就立馬打通任督二脈。 ## 示例程式碼 老規矩,所有的示例程式碼都會上傳至程式碼管理倉庫 Github 和 Gitee 上,方便大家取用。 [示例程式碼-Github](https://github.com/meteor1993/python-learning/tree/master/python-data-analysis/pandas-demo "示例程式碼-Github") [示例程式碼-Gitee](https://gitee.com/inwsy/python-learning/tree/master/python-data-analysis/pandas-demo "示例程式碼