Excel & Python | 水果拼盤——多表拼接 | 09
表的橫向拼接
表的橫向拼接就是在橫向將兩個表依據公共列拼接在一起。
在Excel中實現橫向拼接利用的是vlookup()函式,關於vlookup()函式這裡就不展開了,相信大家應該都很熟悉。
在 Python 中實現橫向拼接利用的 merge()方法,接下來的幾節主要圍繞 merge()方法展開。
連線表的型別
連線表的型別關注的就是待連線的兩個表都是什麼型別,主要有3種情況:一對一、多對一、多對多。
一對一
一對一就是待連線的兩個表的公共列是一對一的,例子如下所示。
如果要將df1和df2這兩個表進行連線,那麼直接使用pd.merge()方法即可,該方法會自動尋找兩個表中的公共列,並將找到的公共列作為連線列。
上面例子中表 df1和 df2的公共列為學號,且學號是一對一的,兩個表執行 pd.merge()方法以後結果如下:
多對一
多對一就是待連線的兩個表的公共列不是一對一的,其中一個表的公共列有重複值,另一個表的公共列是唯一的。
現在有一份名單 df1,其中記錄了每位學生升入高三以後的第一次模擬考試的成績,還有一份名單df2記錄了學號及之後每次模擬考試的成績。要將這兩個表按照學號進行連線,由於這兩個表是多對一關係,df1中的學號是唯一的,但是 df2中的學號不是唯一的,因此拼接結果就是保留df2中的重複值,且在df1中也增加重複值,實現程式碼如下:
多對多
多對多就是待連線的兩個表的公共列不是一對一的,且兩個表中的公共列都有重複值,多對多連線相當於多個多對一連線,看下面這個例子:
連線鍵的型別
預設以公共列作為連線鍵
如果事先沒有指定要按哪個列進行拼接時,pd.merge()方法會預設尋找兩個表中的公共列,然後以這個公共列作為連線鍵進行連線,比如下面這個例子,預設以公共列學號作為連線鍵:
用on來指定連線鍵
也可以用引數on來指定連線鍵,引數on一般指定的也是兩個表中的公共列,其實這個時候和使用預設公共列達到的效果是一樣的。
公共列可以有多列,也就是連線鍵可以有多個,比如下面這個例子用學號和姓名兩列做連線鍵:
分別指定左右連線鍵
當兩個表中沒有公共列時,這裡指的是實際值一樣,但列名不同,否則就無法連線了。
這個時候要分別指定左表和右表的連線鍵,使用的引數分別是left_on和rigth_on, left_on用來指明左表用作連線鍵的列名,right_on用來指明右表用作連線鍵的列名,例子如下:
把索引列當作連線鍵
索引列不算是真正的列,當公共列是索引列時,就要把索引列當作連線鍵,使用的引數分別是 left_index 和 right_index,left_index 用來控制左表的索引,right_index用來控制右表的索引,下例中的左、右表的連線鍵均為各自的索引。
在上面的例子中,左表和右表的連線鍵均為索引。
還可以把索引列和普通列混用,下列左表的連線鍵為索引,右表的連線鍵為普通列。
連線方式
前兩個小節舉的例子比較標準,也就是左表中的公共列的值都可以在右表對應的公共列中找到,右表公共列的值也可以在左表對應的公共列中找到,但是現實業務中很多是互相找不到的,這個時候該怎麼辦呢?這就衍生出了用來處理找不到的情況的幾種連線方式,用引數how來指明具體的連線方式。
內連線 inner
內連線就是取兩個表中的公共部分,在下面的例子中,學號100、101、102是兩個表中的公共部分,內連線以後就只有這三個學號對應的內容。
如果不指明連線方式,則預設都是內連線。
左連線 left
左連線就是以左表為基礎,右表往左表上拼接。下例的右表中沒有學號為103的資訊,拼接過來的資訊就用NaN填充。
右連線 right
右連線就是以右表為基礎,左表往右表上拼接。下例的左表中沒有學號為104的資訊,拼接過來的資訊就用NaN填充。
外連線 outer
外連線就是取兩個表的並集。下例中表df1中學號為100、101、102、103,表df2中學號為100、101、102、104,因此外連線取並集以後的結果中應包含學號為100、101、102、103、104的資訊。
重複列名處理
兩個表進行連線時,經常會遇到列名重複的情況。
在遇到列名重複時,pd.merge()方法會自動給這些重複列名新增字尾_x、_y或_z,而且會根據表中已有的列名自行調整,比如下面這個例子中的姓名列:
當然我們也可以自定義重複的列名,只需要修改引數 suffixes的值即可,預設為["_x","_y"]。
表的縱向拼接
表的縱向拼接式與橫向拼接相對應的,橫向拼接是兩個表依據公共列在水平方向上進行拼接,而縱向拼接是在垂直方向進行拼接。
一般的應用場景就是將分離的若干個結構相同的資料表合併成一個數據表,比如下面是兩個班的花名冊,這兩個表的結構是一樣的,需要把這兩個表進行合併。
在Excel中兩個結構相同的表要實現合併,只需要把表二複製貼上到表一的下方即可。
在Python中想縱向合併兩個表,需要用到concat()方法。
普通合併
普通合併就是直接將待合併表的表名以列表的形式傳給pd.concat()方法,執行程式碼,即可完成合並,例子如下:
這樣就把一班的花名冊和二班的花名冊合併到了一起。
索引設定
pd.concat()方法預設保留原表的索引,合併後的索引列編號就顯示為12341234,但是這樣看著很不順眼。
我們可以通過設定引數ignore_index的值,讓其等於True,這樣就會生成一組新的索引,而不保留原表的索引,如下所示。
重疊資料合併
前面的資料都是比較乾淨的資料,現實中難免會有一些錯誤資料, 比如一班的花名冊裡寫進了二班的人,而這個人在二班的花名冊裡也出現了,這個時候如果直接合並兩個表,肯定會有重複值,那麼該怎麼處理呢?
前面講過的重複值處理是不是可以處理這種情況呢?答案是肯定的,具體實現如下所示。
經過刪除重複值以後,“葛顏”就只出現一次了。
小結
表的橫向拼接
pd.merge() pd.merge(df1,df2,left_on="學號",right_on="編號",how="inner")
連線表 連線鍵的型別
引數 on 宣告連線的欄位(兩個表的欄位名相同)
引數 left_on 左表連線欄位 rigth_on 右表連線欄位 (兩個列名不同,但是值是一樣的)
引數 left_index right_index (True/False) 左右表使用索引來進行表的連線 (也可以一個表用索引,一個表用普通列)
連線方式
引數 how
left right inner outer
表的縱向拼接
pd.concat([df1,df2,..]) pd.concat([df1,df2],ignore_index=True).drop_duplicates()
引數 ignore_index 不要原來的索引 索引重新從0開始
一般合併後會去重 drop_duplicates()