1. 程式人生 > 其它 >DataFrame的merge、join和concat函式

DataFrame的merge、join和concat函式

merge函式

pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None,
         left_index=False, right_index=False, sort=True,
         suffixes=('_x', '_y'), copy=True, indicator=False,
         validate=None)
  • 引數如下:
    • left: 拼接的左側 DataFrame 物件
    • right: 拼接的右側 DataFrame 物件
    • on: 要加入的列或索引級別名稱。 必須在左側和右側 DataFrame 物件中找到。 如果未傳遞且 left_index 和 right_index 為 False,則 DataFrame 中的列的交集將被推斷為連線鍵。
    • left_on: 左側 DataFrame 中的列或索引級別用作鍵。 可以是列名,索引級名稱,也可以是長度等於 DataFrame 長度的陣列。一般用於當資料值相同但是列名不同的情況,需和right_on一起使用。
    • right_on: 左側 DataFrame 中的列或索引級別用作鍵。 可以是列名,索引級名稱,也可以是長度等於 DataFrame 長度的陣列。
    • left_index: 如果為 True,則使用左側 DataFrame 中的索引(行標籤)作為其連線鍵。 對於具有 MultiIndex(分層)的 DataFrame,級別數必須與右側 DataFrame 中的連線鍵數相匹配。
    • right_index: 與 left_index 功能相似。
    • how: ‘left’, ‘right’, ‘outer’, ‘inner’中四選一, 預設 inner。inner 是取交集,outer 取並集,left是左連線,right是右連線。
    • sort: 按字典順序通過連線鍵對結果 DataFrame 進行排序。 預設為 True,設定為 False 將在很多情況下顯著提高效能。
    • suffixes: 用於重疊列的字串字尾元組。 預設為(‘x’,’ y’)。
    • copy: 始終從傳遞的 DataFrame 物件複製資料(預設為 True),即使不需要重建索引也是如此。
    • indicator: 將一列新增到名為_merge 的輸出 DataFrame,其中包含有關每行源的資訊。 _merge 是分類型別,並且對於其合併鍵僅出現在 “左”DataFrame 中的觀察值,取得值為 left_only,對於其合併鍵僅出現在 “右”DataFrame 中的觀察值為 right_only,並且如果在兩者中都找到觀察點的合併鍵,則為 left_only。
In [1]: data1 = {'name': ['小明', '小明', '小澤', '小花', '小花'],
   ...:         'year':[2000, 2001, 2002, 2001, 2002],
   ...:         'pop': [5.1, 1.7, 3.6, 2.4, 3.9]}
   
In [4]: df1 = pd.DataFrame(data1)

In [5]: df1
Out[5]: 
  name  year  pop
0   小明  2000  5.1
1   小明  2001  1.7
2   小澤  2002  3.6
3   小花  2001  2.4
4   小花  2002  3.9

In [6]: data2 = data1 = {'name': ['小明', '小花'],
   ...:                  'year': [2000, 2002],
   ...:                  'money': [1000, 3000]}

In [7]: df2 = pd.DataFrame(data2)

In [8]: df2
Out[8]: 
  name  year  money
0   小明  2000   1000
1   小花  2002   3000
  • inner(內連線)——兩表關聯後,保留兩表共有的鍵。
In [9]: pd.merge(df1, df2, on='name', sort=False)
Out[9]: 
  name  year_x  pop  year_y  money
0   小明    2000  5.1    2000   1000
1   小明    2001  1.7    2000   1000
2   小花    2001  2.4    2002   3000
3   小花    2002  3.9    2002   3000


# 可以使用list來給on提供引數
In [10]: pd.merge(df1, df2, on=['name', 'year'], sort=False)
Out[10]: 
  name  year  pop  money
0   小明  2000  5.1   1000
1   小花  2002  3.9   3000
  • outer(外連線)——兩表關聯後,保留兩表所有的鍵
In [11]: pd.merge(df1, df2, how='outer', on='name', sort=False)
Out[11]: 
  name  year_x  pop  year_y   money
0   小明    2000  5.1  2000.0  1000.0
1   小明    2001  1.7  2000.0  1000.0
2   小澤    2002  3.6     NaN     NaN
3   小花    2001  2.4  2002.0  3000.0
4   小花    2002  3.9  2002.0  3000.0

# left_on和right_on用於列名不一樣的情況,這裡都是name只是為了說明情況
In [12]: pd.merge(df1, df2, how='outer', left_on='name', right_on='name', sort=False)
Out[12]: 
  name  year_x  pop  year_y   money
0   小明    2000  5.1  2000.0  1000.0
1   小明    2001  1.7  2000.0  1000.0
2   小澤    2002  3.6     NaN     NaN
3   小花    2001  2.4  2002.0  3000.0
4   小花    2002  3.9  2002.0  3000.0
  • left和right
# 以right,也就是以df2的name為準,因此只包括小明、小花
In [13]: pd.merge(df1, df2, how='right', on='name', sort=False)
Out[13]: 
  name  year_x  pop  year_y  money
0   小明    2000  5.1    2000   1000
1   小明    2001  1.7    2000   1000
2   小花    2001  2.4    2002   3000
3   小花    2002  3.9    2002   3000

# 以left,也就是以df1的name為準,因此包括小明、小花和小澤
In [14]: pd.merge(df1, df2, how='left', on='name', sort=False)
Out[14]: 
  name  year_x  pop  year_y   money
0   小明    2000  5.1  2000.0  1000.0
1   小明    2001  1.7  2000.0  1000.0
2   小澤    2002  3.6     NaN     NaN
3   小花    2001  2.4  2002.0  3000.0
4   小花    2002  3.9  2002.0  3000.0

join函式

merge是基於columns來連線DataFrame,join函式是基於index連線DataFrame。

DataFrame.join(other, on=None, how=’left’, lsuffix=”, rsuffix=”, sort=False)

  • 引數說明
    • other:【DataFrame,或者帶有名字的Series,或者DataFrame的list】如果傳遞的是Series,那麼其name屬性應當是一個集合,並且該集合將會作為結果DataFrame的列名
    • on:【列名稱,或者列名稱的list/tuple,或者類似形狀的陣列】連線的列,預設使用索引連線
    • how:【{‘left’, ‘right’, ‘outer’, ‘inner’}, default:‘left’】連線的方式,預設為左連線
    • lsuffix:【string】左DataFrame中重複列的字尾
    • rsuffix:【string】右DataFrame中重複列的字尾
    • sort:【boolean, default=False】按照字典順序對結果在連線鍵上排序。如果為False,連線鍵的順序取決於連線型別(關鍵字)。
In [15]: caller = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3', 'K4', 'K5'], 'A': ['A0', 'A1', 'A
    ...: 2', 'A3', 'A4', 'A5']})

In [16]: caller
Out[16]: 
  key   A
0  K0  A0
1  K1  A1
2  K2  A2
3  K3  A3
4  K4  A4
5  K5  A5

In [17]: other = pd.DataFrame({'key': ['K0', 'K1', 'K2'],'B': ['B0', 'B1', 'B2']})

In [18]: other
Out[18]: 
  key   B
0  K0  B0
1  K1  B1
2  K2  B2

In [19]: caller.join(other, lsuffix='_caller', rsuffix='_other', sort=False)
Out[19]: 
  key_caller   A key_other    B
0         K0  A0        K0   B0
1         K1  A1        K1   B1
2         K2  A2        K2   B2
3         K3  A3       NaN  NaN
4         K4  A4       NaN  NaN
5         K5  A5       NaN  NaN

concat函式

concat方法是拼接函式,有行拼接和列拼接,預設是行拼接,拼接方法預設是外拼接(並集),拼接的物件是pandas資料型別。

pd.concat(objs, axis=0, join='outer', join_axes=None, ignore_index=False,
          keys=None, levels=None, names=None, verify_integrity=False,
          copy=True)
  • 引數說明
    • objs: series,dataframe或者是panel構成的序列lsit。
    • axis: 需要合併連結的軸,0是行,1是列。
    • join:連線的方式 inner,或者outer。
    • ignore_index:boolean,default False。如果為True,請不要使用並置軸上的索引值。結果軸將被標記為0,...,n-1。如果要連線其中並置軸沒有有意義的索引資訊的物件,這將非常有用。注意,其他軸上的索引值在連線中仍然受到尊重。
    • join_axes:Index物件列表。用於其他n-1軸的特定索引,而不是執行內部/外部設定邏輯。
    • keys:序列,預設值無。使用傳遞的鍵作為最外層構建層次索引。如果為多索引,應該使用元組。
    • levels:序列列表,預設值無。用於構建MultiIndex的特定級別(唯一值)。否則,它們將從鍵推斷。
    • names:list,default無。結果層次索引中的級別的名稱。
    • verify_integrity:boolean,default False。檢查新連線的軸是否包含重複項。這相對於實際的資料串聯可能是非常昂貴的。
    • copy:boolean,default True。如果為False,請勿不必要地複製資料。
In [20]: df1 = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3', 'K4', 'K5'], 'A': ['A0', 'A1', 'A2', 'A
    ...: 3', 'A4', 'A5']})

In [21]: df1
Out[21]: 
  key   A
0  K0  A0
1  K1  A1
2  K2  A2
3  K3  A3
4  K4  A4
5  K5  A5

In [22]: df2 = pd.DataFrame({'key': ['K0', 'K1', 'K2'],'B': ['B0', 'B1', 'B2']})

In [23]: df2
Out[23]: 
  key   B
0  K0  B0
1  K1  B1
2  K2  B2

In [24]: pd.concat([df1, df2])
Out[24]: 
  key    A    B
0  K0   A0  NaN
1  K1   A1  NaN
2  K2   A2  NaN
3  K3   A3  NaN
4  K4   A4  NaN
5  K5   A5  NaN
0  K0  NaN   B0
1  K1  NaN   B1
2  K2  NaN   B2

# outer取並集
In [25]: pd.concat([df1, df2], join='outer')
Out[25]: 
  key    A    B
0  K0   A0  NaN
1  K1   A1  NaN
2  K2   A2  NaN
3  K3   A3  NaN
4  K4   A4  NaN
5  K5   A5  NaN
0  K0  NaN   B0
1  K1  NaN   B1
2  K2  NaN   B2

# inner取交集
In [26]: pd.concat([df1, df2], join='inner')
Out[26]: 
  key
0  K0
1  K1
2  K2
3  K3
4  K4
5  K5
0  K0
1  K1
2  K2

# axis=1,設定在列上合併
In [27]: pd.concat([df1, df2], join='inner', axis=1)
Out[27]: 
  key   A key   B
0  K0  A0  K0  B0
1  K1  A1  K1  B1
2  K2  A2  K2  B2
時來天地皆同力,運去英雄不自由。