小白學 Python 數據分析(13):Pandas (十二)數據表拼接
- 2020 年 3 月 7 日
- 筆記
人生苦短,我用 Python
前文傳送門:
小白學 Python 數據分析(2):Pandas (一)概述
小白學 Python 數據分析(3):Pandas (二)數據結構 Series
小白學 Python 數據分析(4):Pandas (三)數據結構 DataFrame
小白學 Python 數據分析(5):Pandas (四)基礎操作(1)查看數據
小白學 Python 數據分析(6):Pandas (五)基礎操作(2)數據選擇
小白學 Python 數據分析(7):Pandas (六)數據導入
小白學 Python 數據分析(8):Pandas (七)數據預處理
小白學 Python 數據分析(9):Pandas (八)數據預處理(2)
小白學 Python 數據分析(10):Pandas (九)數據運算
小白學 Python 數據分析(11):Pandas (十)數據分組
小白學 Python 數據分析(12):Pandas (十一)數據透視表(pivot_table)
引言
說到數據表拼接,就不得不提一下 SQL ,對於熟悉 SQL 的同學來講,這並不是一個難以理解的概念,數據表之間的關係可以分為以下這三種:
一對一
兩個表之間的公共列是一對一的。
這裡的示例我們就不用圖片了,直接使用程式碼來做展示,原因嘛就是小編懶的畫了:
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()
方法:
print(pd.merge(df1, df2)) # 輸出內容 編號 姓名 分數 班級 0 100 小明 96 1 1 200 小紅 48 2 2 300 小王 72 3 3 400 小剛 72 4
在我們使用 merge()
方法的時候, merge()
方法會自動尋找兩個表中的公共列,並且自動的進行對應操作。
一對多
兩個表之間的公共列不是一對一的,而是其中一個表的公共列是唯一的,另一個表的公共列則會有重複的數據。
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
指明判斷的條件:
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 進行連接操作:
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 能和前面的數據保持一致:
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
屬性是用來指定連接類型的。
左連接
左連接就是已左表為基礎,右表像左表上拼數據:
# 左連接 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 。
右連接
右連接正好和上面的左連接相反,已右表為基礎,左表往右表上拼數據:
# 右連接 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
外連接
外連接就是兩個表的並集:
# 外連接 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()
:
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
,讓其不在保留原有索引,而是生成新的索引:
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 上,方便大家取用。