1. 程式人生 > >數據規整化——合並

數據規整化——合並

技術 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)})
#多對多產生的是行的笛卡爾積 left
pd.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)
技術分享圖片技術分享圖片
concat函數的參數
參數 說明
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
‘‘‘

數據規整化——合並