1. 程式人生 > >pandas 表的合併 merge/join/contact

pandas 表的合併 merge/join/contact

最近做比賽的特徵工程時,經常用到表的合併,對上述三種操作總是不是熟練的使用,弄不清其中的區別與聯絡。所以花點時間弄清他們。

merge操作

merge通過一個或者多個鍵將兩張表合併在一起,api如下

merge(left,right,how='inner',on=None,left_on=None,right_on=None,
left_index=False,right_index=False,sort=False,suffixes=('_x','_y'),copy=True)

其中:

  • on指定合併時依據的列名,單列時後跟字串,多列時後跟字串列表
  • how 表示連線方式,inner
    交集,outer並集,leftright表示根據某一邊
    當僅有兩個引數merge(left,right)時,on預設的是相同列名,how預設為inner
  • suffixes 引數指定當兩個表合併後有相同的列名時,在列名上加的字首,預設為元組('_x','_y')
  • left_on=None,right_on=None,兩個表的列名不同卻要根據這兩個列名下的屬性值來合併的時候使用
    eg:
data1 = pd.DataFrame({
    'a': [1, 1, 3, 4],
    'b': [5, 6, 7, 8],

})

data2 = pd.DataFrame(
{ 'a': [1, 1, 4], "b":[5,6,0], 'c': [9, 10, 12], 'd': [13, 14, 16] })

==>

   a  b
0  1  5
1  1  6
2  3  7
3  4  8
   a  b   c   d
0  1  5   9  13
1  1  6  10  14
2  4  0  12  16
print(pd.merge(data1,data2,on=["a","b"],how="outer"))
print(pd.merge(data1,data2))

==>

   a  b     c     d
0
1 5 9.0 13.0 1 1 6 10.0 14.0 2 3 7 NaN NaN 3 4 8 NaN NaN 4 4 0 12.0 16.0 a b c d 0 1 5 9 13 1 1 6 10 14
suffixes:
data1 = pd.DataFrame({
    'a': [1, 1, 3, 4],
    'b': [5, 6, 7, 8],

})

data2 = pd.DataFrame({
    'a': [1, 1,  4],
    "b":[5,6,0],
    'c': [9, 10,  12],
    'd': [13, 14,  16]
})
res = pd.merge(data1,data2,on="a",suffixes=("_left","_right"),how="inner")
print(res)

==>

   a  b_left  b_right   c   d
0  1       5        5   9  13
1  1       5        6  10  14
2  1       6        5   9  13
3  1       6        6  10  14
4  4       8        0  12  16
left_on ,right_on
data1 = pd.DataFrame({
    'a': [1, 2, 3, 4],
    'b': [5, 6, 7, 8],

})

data2 = pd.DataFrame({
    'c': [1, 10,  12],
    'd': [13, 14,  16]
})

res = pd.merge(data1,data2,left_on="a",right_on="c",how="outer")
print(res)

==>

     a    b     c     d
0  1.0  5.0   1.0  13.0
1  2.0  6.0   NaN   NaN
2  3.0  7.0   NaN   NaN
3  4.0  8.0   NaN   NaN
4  NaN  NaN  10.0  14.0
5  NaN  NaN  12.0  16.0

應用場景:
比如分同時對資料進行求多項式特徵和求交叉特徵,得到的data1和data2,公共部分為id,則可以根據id把這兩部分的資料合併起來。


join操作

用來拼接列,拼接的依據為索引。
這說一下,其實pandas中的merge操作更類似於mysql中的join,而pandas中的join和mysql中的join卻相差甚。
API如下

join(self, other, on=None, how='left', lsuffix='', rsuffix='',sort=False):

上述引數中除了how的預設值為“left”外其他的都和merge相同。
eg:
兩個不含公共列的表進行合併,前提按照index進行合併


data1 = pd.DataFrame({
    'a': [1, 1, 3, 4],
    'b': [5, 5, 7, 8],

})

data2 = pd.DataFrame({
    'c': [1, 10, 12,0],
    'd': [13, 14,16,8]
})
res = data1.join(data2)
print(res)

==>

   a  b   c   d
0  1  5   1  13
1  1  5  10  14
2  3  7  12  16
3  4  8   0   8

index不同時

data1 = pd.DataFrame({
    'a': [1, 1, 3, 4],
    'b': [5, 5, 7, 8],

})

data2 = pd.DataFrame({
    'c': [1, 10, 12,0],
    'd': [13, 14,16,8]
})
data1 = data1.drop_duplicates()
res = data1.join(data2)
print(res)

==>

   a  b   c   d
0  1  5   1  13
2  3  7  12  16
3  4  8   0   8

在使用join的時候千萬要注意index的變化,注意drop_duplicates()reset_index()等會改變index的操作


contact 操作

contact 是根據軸來合併兩張表,可以理解為左右合併和上下合併
API

 concat(objs, axis=0, join='outer', join_axes=None, ignore_index=False,
           keys=None, levels=None, names=None, verify_integrity=False, copy=True)
上下拼接 axis=0

上下拼接時,依據是列名

data1 = pd.DataFrame({
    'a': [1,2],
    'b': [3,4],

})
data2 = pd.DataFrame({
    'a': [5,6],
    'b': [7,8]
})
data =pd.concat([data1,data2],axis=0)
print(data)
   a  b
0  1  3
1  2  4
0  5  7
1  6  8

注意索引

左右拼接 axis=1

左右拼接時,依據是index

data1 = pd.DataFrame({
    'a': [1,2,9],
    'b': [3,4,9],

})
data2 = pd.DataFrame({
    'a': [5,6],
    'b': [7,8]
})
data =pd.concat([data1,data2],axis=1)
print(data)

==>

   a  b    a    b
0  1  3  5.0  7.0
1  2  4  6.0  8.0
2  9  9  NaN  NaN

小結

在使用這三個方法前,我們要明確我們要根據什麼key來合併。根據index,建議使用join,根據列名建議使用merge。如何不需要兩張表產生融合而只是拼接,可以使用contact.