數據規整化——合並
阿新 • • 發佈:2018-02-21
技術 als 發現 one 層次 分享圖片 eve iss 分層
數據集的合並或連接運算是通過一個或多個鍵將行鏈接起來的,而pandas的merge函數是對數據應用這些算法的主要切入點。
一對多:df1的數據有多個被標記為a和b的行,而df2中key列的每個值則僅對應一行。
df1 = DataFrame({‘key‘: [‘b‘, ‘b‘, ‘a‘, ‘c‘, ‘a‘, ‘a‘, ‘b‘], ‘data1‘: range(7)}) df2 = DataFrame({‘key‘: [‘a‘, ‘b‘, ‘d‘], ‘data2‘: range(3)})
註意:若沒有指定哪個列進行連接,則默認將重疊列的列名當作鍵。
pd.merge(df1, df2) pd.merge(df1, df2, on=‘key‘)
若兩個對象的列名不同,也可以分別進行指定:
df3 = DataFrame({‘lkey‘: [‘b‘, ‘b‘, ‘a‘, ‘c‘, ‘a‘, ‘a‘, ‘b‘], ‘data1‘: range(7)}) df4 = DataFrame({‘rkey‘: [‘a‘, ‘b‘, ‘d‘], ‘data2‘: range(3)}) pd.merge(df3, df4, left_on=‘lkey‘, right_on=‘rkey‘) #默認merge做的事inner連接,結果是鍵的交集,其他方式有left、right、outer pd.merge(df1, df2, how=‘outer‘)
多對多:
df1 = DataFrame({‘key‘: [‘b‘, ‘b‘, ‘a‘, ‘c‘, ‘a‘, ‘b‘], ‘data1‘: range(6)}) df2 = DataFrame({‘key‘: [‘a‘, ‘b‘, ‘a‘, ‘b‘, ‘d‘], ‘data2‘: range(5)}) #多對多產生的是行的笛卡爾積 leftpd.merge(df1, df2, on=‘key‘, how=‘left‘) #連接方式只影響出現在結果中的鍵 inner pd.merge(df1, df2, how=‘inner‘)
若要根據多個鍵進行合並,需傳入一個由列名組成的列表:
left = DataFrame({‘key1‘: [‘foo‘, ‘foo‘, ‘bar‘], ‘key2‘: [‘one‘, ‘two‘, ‘one‘], ‘lval‘: [1, 2, 3]}) right = DataFrame({‘key1‘: [‘foo‘, ‘foo‘, ‘bar‘, ‘bar‘], ‘key2‘: [‘one‘, ‘one‘, ‘one‘, ‘two‘], ‘rval‘: [4, 5, 6, 7]}) pd.merge(left, right, on=[‘key1‘, ‘key2‘], how=‘outer‘)
對於合並運算需要考慮的最後一個問題是對重復列名的處理。而merge的suffixes選項,正用於指定附加到左右兩個dataframe對象的重復列名上的字符串:
pd.merge(left, right, on=‘key1‘) pd.merge(left, right, on=‘key1‘, suffixes=(‘_left‘, ‘_right‘))
索引的合並:有時候連接鍵位於其索引中,則可以傳入left_index=True或right_index=True以說明索引應該被用作連接鍵。
left1 = DataFrame({‘key‘: [‘a‘, ‘b‘, ‘a‘, ‘a‘, ‘b‘, ‘c‘], ‘value‘: range(6)}) right1 = DataFrame({‘group_val‘: [3.5, 7]}, index=[‘a‘, ‘b‘]) pd.merge(left1, right1, left_on=‘key‘, right_index=True) #外連接 pd.merge(left1, right1, left_on=‘key‘, right_index=True, how=‘outer‘)
層次化索引數據,必須以列表的形式指明用作合並鍵的多個列
lefth = DataFrame({‘key1‘: [‘Ohio‘, ‘Ohio‘, ‘Ohio‘, ‘Nevada‘, ‘Nevada‘], ‘key2‘: [2000, 2001, 2002, 2001, 2002], ‘data‘: np.arange(5.)}) righth = DataFrame(np.arange(12).reshape((6, 2)), index=[[‘Nevada‘, ‘Nevada‘, ‘Ohio‘, ‘Ohio‘, ‘Ohio‘, ‘Ohio‘], [2001, 2000, 2000, 2000, 2001, 2002]], columns=[‘event1‘, ‘event2‘])
pd.merge(lefth, righth, left_on=[‘key1‘, ‘key2‘], right_index=True) pd.merge(lefth, righth, left_on=[‘key1‘, ‘key2‘], right_index=True, how=‘outer‘)
直接合並雙方的索引也可以:
left2 = DataFrame([[1., 2.], [3., 4.], [5., 6.]], index=[‘a‘, ‘c‘, ‘e‘], columns=[‘Ohio‘, ‘Nevada‘]) right2 = DataFrame([[7., 8.], [9., 10.], [11., 12.], [13, 14]], index=[‘b‘, ‘c‘, ‘d‘, ‘e‘], columns=[‘Missouri‘, ‘Alabama‘])
pd.merge(left2, right2, how=‘outer‘, left_index=True, right_index=True) #join實例方法,更為方便地按索引合並 left2.join(right2, how=‘outer‘)
軸向連接:pd.concatenation 簡單數據連接
arr = np.arange(12).reshape((3, 4)) ‘‘‘ array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]]) ‘‘‘ np.concatenate([arr, arr], axis=1) ‘‘‘ array([[ 0, 1, 2, 3, 0, 1, 2, 3], [ 4, 5, 6, 7, 4, 5, 6, 7], [ 8, 9, 10, 11, 8, 9, 10, 11]]) ‘‘‘
pandas的concat函數提供了一種能夠軸向連接的方式。
s1 = Series([0, 1], index=[‘a‘, ‘b‘]) s2 = Series([2, 3, 4], index=[‘c‘, ‘d‘, ‘e‘]) s3 = Series([5, 6], index=[‘f‘, ‘g‘]) pd.concat([s1, s2, s3]) #默認concat的axis=0返回Series對象,而axis=1則返回dataframe對象 pd.concat([s1, s2, s3], axis=1)
參數 | 說明 |
objs | 參與連接的pandas對象的列表或者字典,唯一的必須參數 |
axis | 指明連接的軸向,默認0 |
join | 選項包括inner(交集)、outer(並集) |
join_axes | 指明用於其他(n-1)條軸的索引,不執行並集或交集運算 |
keys | 與連接對象有關的值,用於形成連接軸向上的層次化索引。可以是任意值的列表或數組 |
levels | 指定用作層次化索引各級別上的索引(若設置了keys的話) |
names | 用於創建分層級別的名稱(若設置了keys和levels的話) |
verify_integrity | 檢查結果對象新軸上的重復情況,若發現則異常,默認允許重復(false) |
ignore_index | 不保留連接軸上的索引,產生一組新索引 |
合並重疊數據:Series中combine_first方法,dataframe也可以使用
a = Series([np.nan, 2.5, np.nan, 3.5, 4.5, np.nan], index=[‘f‘, ‘e‘, ‘d‘, ‘c‘, ‘b‘, ‘a‘]) b = Series(np.arange(len(a), dtype=np.float64), index=[‘f‘, ‘e‘, ‘d‘, ‘c‘, ‘b‘, ‘a‘]) #np.where方法 np.where(pd.isnull(a), b, a) ‘‘‘ array([ 0. , 2.5, 2. , 3.5, 4.5, nan]) ‘‘‘ #combine_first方法 b[:-2].combine_first(a[2:]) ‘‘‘ a NaN b 4.5 c 3.0 d 2.0 e 1.0 f 0.0 dtype: float64 ‘‘‘
數據規整化——合並