Pandas數據處理之合併數據集merge()

3.8 合併數據集:合併與連接

  Pandas的基本特性之一就是高性能的內存式數據鏈接(join)和合並(merge)操作。

3.8.1 數據鏈接的類型

  pd.merge()函數實現了三種數據鏈接的類型:一對一、多對一和多對多。這三種數據連接類型都通過pd.merge()接口進行調用。

1.一對一連接

In [1] :import pandas as pd
In [2] :df1 = pd.DataFrame({'employee': ['Bob', 'Jake', 'Lisa', 'Sue'],'group': ['Accounting', 'Engineering', 'Engineering', 'HR']})
		df2 = pd.DataFrame({'employee': ['Lisa', 'Bob', 'Jake', 'Sue'],'hire_date': [2004, 2008, 2012, 2014]})

In [3] :df1
Out[3] :
	employee	group
0	Bob		Accounting
1	Jake	Engineering
2	Lisa	Engineering
3	Sue			HR

In [4] :df2
Out[4] :
	employee	hire_date
0	Lisa		2004
1	Bob			2008
2	Jake		2012
3	Sue			2014

  可以看到,兩個df有共同列‘employee ’,若想將這兩個DataFrame合併成一個DataFrame,可以使用pd.merge(),並且會自動以相同列作爲key進行連接:

In [5] :df3 = pd.merge(df1,df2)
		df3
Out[5] :
  employee	group	  hire_date
0	Bob		Accounting	2008
1	Jake	Engineering	2012
2	Lisa	Engineering	2004
3	Sue		HR			2014

兩個df的合併會生成一個新的DataFrame。而且,pd.merge()會默認丟棄原來的行索引,重新生成一個整數行索引。

1.多對一連接

  多對一連接是指,在需要連接的兩個列中,有一列的值有重複。通過多對一連接獲得的結果DataFrame將會保留重複值。

In [6] :df4 = pd.DataFrame({'group': ['Accounting', 'Engineering', 'HR'],'supervisor': ['Carly', 'Guido', 'Steve']})
		df4
Out[6] :
	group		supervisor
0	Accounting	  Carly
1	Engineering	  Guido
2	HR			  Steve
In [7] :pd.merge(df3,df4)
Out[7] :
	employee	group	hire_date	supervisor
0	Bob		Accounting	  2008		Carly
1	Jake	Engineering	  2012		Guido
2	Lisa	Engineering	  2004		Guido
3	Sue		HR			  2014		Steve

  對於df4中的group列,因爲df3中group列擁有兩個‘Engineering’,所以會自動生成與其對應的連接值。

3.多對多連接

  可以理解爲,如果左右兩個輸入的共同列都包含重複值,那麼合併的結果就是一種多對多連接。

In [8] :df5 = pd.DataFrame({'group': ['Accounting', 'Accounting','Engineering', 'Engineering', 'HR', 'HR'],'skills': ['math', 'spreadsheets', 'coding', 'linux',
'spreadsheets', 'organization']})
		df5
Out[8] :
	  group		skills
0	Accounting	math
1	Accounting	spreadsheets
2	Engineering	coding
3	Engineering	linux
4		HR		spreadsheets
5		HR		organization

In [9] :pd.merge(df1,df5)
Out[9] :
	employee	group	skills
0	Bob		Accounting	math
1	Bob		Accounting	spreadsheets
2	Jake	Engineering	coding
3	Jake	Engineering	linux
4	Lisa	Engineering	coding
5	Lisa	Engineering	linux
6	Sue			HR		spreadsheets
7	Sue			HR		organization

這三種數據連接類型可以直接與其他Pandas 工具組合使用,從而實現各種各樣的功
能。

3.8.2 設置數據合併的鍵

  上面所介紹的合併都是擁有共同列名的兩個DataFrame之間的合併,可在工作中更常見的是意義相同,列名卻不同的兩個DataFrame進行合併。pd.merge()提供了一些參數處理這個問題。

1. 參數on的用法

  最簡單的方法就是直接將參數on 設置爲一個列名字符串或者一個包含多列名稱的列表:
對於擁有相同列的df使用

In [10] :pd.merge(df1, df2, on='employee')
Out[10] :
	employee	group	hire_date
0	Bob		Accounting	2008
1	Jake	Engineering	2012
2	Lisa	Engineering	2004
3	Sue			HR		2014

2. left_on與right_on參數

  有時你也需要合併兩個列名不同的數據集,例如前面的員工信息表中有一個字段不是
“employee”而是“name”。在這種情況下,就可以用left_on 和right_on 參數來指定
列名:

In [11] :df3 = pd.DataFrame({'name': ['Bob', 'Jake', 'Lisa', 'Sue'],'salary': [70000, 80000, 120000, 90000]})
In [12] :pd.merge(df1, df3, left_on="employee", right_on="name")
Out[12] :
	employee	group	name	salary
0	Bob		Accounting	Bob		70000
1	Jake	Engineering	Jake	80000
2	Lisa	Engineering	Lisa	120000
3	Sue			HR		Sue		90000

3. left_index與right_index參數

  除了合併列之外,你可能還需要合併索引。就像下面例子中的數據那樣:

In [13] :df1a = df1.set_index('employee')
		 df2a = df2.set_index('employee')
		 
In [14] :df1a

			group
employee	
Bob		Accounting
Jake	Engineering
Lisa	Engineering
Sue			HR

In [14] :df2a
		hire_date
employee	
Lisa	2004
Bob		2008
Jake	2012
Sue		2014

In [15] :pd.merge(df1a,df2a,left_index=True,right_index=True)	# 參數必須同時爲True,否則報錯
Out[15] :
			group	hire_date
employee		
Bob		Accounting	2008
Jake	Engineering	2012
Lisa	Engineering	2004
Sue			HR		2014

3.8.3 設置數據連接的集合操作規則

  pd.merge()合併兩個DataFrame時,默認求交集,這種連接方式被稱爲內連接。

In [15] :df6 = pd.DataFrame({'name': ['Peter', 'Paul', 'Mary'],'food': ['fish', 'beans', 'bread']},columns=['name', 'food'])
In [16] :df7 = pd.DataFrame({'name': ['Mary', 'Joseph'],'drink': ['wine', 'beer']},columns=['name', 'drink'])

In [17] :df6
Out[17] :
	name	food
0	Peter	fish
1	Paul	beans
2	Mary	bread

In [18] :df7
Out[18] :
	name	drink
0	Mary	wine
1	Joseph	beer

In [19] :pd.merge(df6,df7)
Out[19] :
	name	food	drink
0	Mary	bread	wine

  我們可以用how參數設置連接方式,默認爲‘innner’

In [20] :pd.merge(df6, df7, how='inner')
Out[20] :
	name	food	drink
0	Mary	bread	wine

  外連接outer,也就是求並集,缺失值用NaN填充:

In [21] :pd.merge(df6,df7,how="outer")
Out[21] :
name	food	drink
0	Peter	fish	NaN
1	Paul	beans	NaN
2	Mary	bread	wine
3	Joseph	NaN	beer

  左連接left,只包含相同列左邊的值:

In [22] :pd.merge(df6,df7,how="outer")
Out[22] :
	name	food	drink
0	Peter	fish	NaN
1	Paul	beans	NaN
2	Mary	bread	wine
3	Joseph	NaN		beer

  右連接right,只包含相同列右邊的值:

In [23] :pd.merge(df6,df7,how="right")
Out[23] :
	name	food	drink
0	Mary	bread	wine
1	Joseph	NaN		beer

3.8.4 重複列名:suffixes參數

  最後,你可能會遇到兩個輸入DataFrame 有重名列的情況。來看看下面的例子:

In [24] :df8 = pd.DataFrame({'name': ['Bob', 'Jake', 'Lisa', 'Sue'],'rank': [1, 2, 3, 4]})
		 df9 = pd.DataFrame({'name': ['Bob', 'Jake', 'Lisa', 'Sue'],'rank': [3, 1, 4, 2]})
		 
In [25] :df8
Out[23] :
	name	rank
0	Bob		1
1	Jake	2
2	Lisa	3
3	Sue		4

In [25] :df9
Out[23] :
	name	rank
0	Bob		3
1	Jake	1
2	Lisa	4
3	Sue		2

# 對於這種所有列名都相同的DF,必須制定合併key,除非完全相同,否則沒有結果
In [26] :pd.merge(df8,df9)
Out[26] :
	name	rank
	
In [27] :pd.merge(df8,df9,on="name") 
Out[27] :
	name	rank_x	rank_y
0	Bob		1		3
1	Jake	2		1
2	Lisa	3		4
3	Sue		4		2

由於輸出結果中有兩個重複的列名,因此pd.merge() 函數會自動爲它們增加後綴_x 或_y,當然也可以通過suffixes 參數自定義後綴名:

In [28] :pd.merge(df8,df9,on="name",suffixes=["_L","_R"])
Out[28] :

	name	rank_L	rank_R
0	Bob		1		3
1	Jake	2		1
2	Lisa	3		4
3	Sue		4		2
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章