pandas dataframe的合並(append, merge, concat)


創建2個DataFrame:
>>> df1 = pd.DataFrame(np.ones((4, 4))*1, columns=list('DCBA'), index=list('4321'))
>>> df2 = pd.DataFrame(np.ones((4, 4))*2, columns=list('FEDC'), index=list('6543'))
>>> df3 = pd.DataFrame(np.ones((4, 4))*3, columns=list('FEBA'), index=list('6521'))
>>> df1
    D    C    B    A
4  1.0  1.0  1.0  1.0
3  1.0  1.0  1.0  1.0
2  1.0  1.0  1.0  1.0
1  1.0  1.0  1.0  1.0
>>> df2
    F    E    D    C
6  2.0  2.0  2.0  2.0
5  2.0  2.0  2.0  2.0
4  2.0  2.0  2.0  2.0
3  2.0  2.0  2.0  2.0
>>> df3
    F    E    B    A
6  3.0  3.0  3.0  3.0
5  3.0  3.0  3.0  3.0
2  3.0  3.0  3.0  3.0
1  3.0  3.0  3.0  3.0

  

1,concat

pd.concat(objs, axis=0, join='outer', join_axes=None, ignore_index=False,
          keys=None, levels=None, names=None, verify_integrity=False,
          copy=True)

 示例:

>>> pd.concat([df1, df2])
    A    B    C    D    E    F
4  1.0  1.0  1.0  1.0  NaN  NaN
3  1.0  1.0  1.0  1.0  NaN  NaN
2  1.0  1.0  1.0  1.0  NaN  NaN
1  1.0  1.0  1.0  1.0  NaN  NaN
6  NaN  NaN  2.0  2.0  2.0  2.0
5  NaN  NaN  2.0  2.0  2.0  2.0
4  NaN  NaN  2.0  2.0  2.0  2.0
3  NaN  NaN  2.0  2.0  2.0  2.0

  

1.1,axis

默認值:axis=0

axis=0:豎方向(index)合並,合並方向index作列表相加,非合並方向columns取並集

axis=1:橫方向(columns)合並,合並方向columns作列表相加,非合並方向index取並集

axis=0:

>>> pd.concat([df1, df2], axis=0)
    A    B    C    D    E    F
4  1.0  1.0  1.0  1.0  NaN  NaN
3  1.0  1.0  1.0  1.0  NaN  NaN
2  1.0  1.0  1.0  1.0  NaN  NaN
1  1.0  1.0  1.0  1.0  NaN  NaN
6  NaN  NaN  2.0  2.0  2.0  2.0
5  NaN  NaN  2.0  2.0  2.0  2.0
4  NaN  NaN  2.0  2.0  2.0  2.0
3  NaN  NaN  2.0  2.0  2.0  2.0 

axis=1:

>>> pd.concat([df1, df2], axis=1)
    D    C    B    A    F    E    D    C
1  1.0  1.0  1.0  1.0  NaN  NaN  NaN  NaN
2  1.0  1.0  1.0  1.0  NaN  NaN  NaN  NaN
3  1.0  1.0  1.0  1.0  2.0  2.0  2.0  2.0
4  1.0  1.0  1.0  1.0  2.0  2.0  2.0  2.0
5  NaN  NaN  NaN  NaN  2.0  2.0  2.0  2.0
6  NaN  NaN  NaN  NaN  2.0  2.0  2.0  2.0

備注:原df中,取並集的行/列名稱不能有重復項,即axis=0時columns不能有重復項,axis=1時index不能有重復項:

>>> df1.columns = list('DDBA')
>>> pd.concat([df1, df2], axis=0)
ValueError: Plan shapes are not aligned

 

1.2,join

默認值:join=‘outer’

非合並方向的行/列名稱:取交集(inner),取並集(outer)。

axis=0時join='inner',columns取交集:

>>> pd.concat([df1, df2], axis=0, join='inner')
    D    C
4  1.0  1.0
3  1.0  1.0
2  1.0  1.0
1  1.0  1.0
6  2.0  2.0
5  2.0  2.0
4  2.0  2.0
3  2.0  2.0

axis=1時join='inner',index取交集:

>>> pd.concat([df1, df2], axis=1, join='inner')
    D    C    B    A    F    E    D    C
4  1.0  1.0  1.0  1.0  2.0  2.0  2.0  2.0
3  1.0  1.0  1.0  1.0  2.0  2.0  2.0  2.0

 

1.3,join_axes

默認值:join_axes=None,取並集

合並后,可以設置非合並方向的行/列名稱,使用某個df的行/列名稱

axis=0時join_axes=[df1.columns],合並后columns使用df1的:

>>> pd.concat([df1, df2], axis=0, join_axes=[df1.columns])
    D    C    B    A
4  1.0  1.0  1.0  1.0
3  1.0  1.0  1.0  1.0
2  1.0  1.0  1.0  1.0
1  1.0  1.0  1.0  1.0
6  2.0  2.0  NaN  NaN
5  2.0  2.0  NaN  NaN
4  2.0  2.0  NaN  NaN
3  2.0  2.0  NaN  NaN

axis=1時axes=[df1.index],合並后index使用df2的:

pd.concat([df1, df2], axis=1, join_axes=[df1.index])
    D    C    B    A    F    E    D    C
4  1.0  1.0  1.0  1.0  2.0  2.0  2.0  2.0
3  1.0  1.0  1.0  1.0  2.0  2.0  2.0  2.0
2  1.0  1.0  1.0  1.0  NaN  NaN  NaN  NaN
1  1.0  1.0  1.0  1.0  NaN  NaN  NaN  NaN 

同時設置join和join_axes的,以join_axes為准:

>>> pd.concat([df1, df2], axis=0, join='inner', join_axes=[df1.columns])
    D    C    B    A
4  1.0  1.0  1.0  1.0
3  1.0  1.0  1.0  1.0
2  1.0  1.0  1.0  1.0
1  1.0  1.0  1.0  1.0
6  2.0  2.0  NaN  NaN
5  2.0  2.0  NaN  NaN
4  2.0  2.0  NaN  NaN
3  2.0  2.0  NaN  NaN

  

1.4,ignore_index

默認值:ignore_index=False

合並方向是否忽略原行/列名稱,而采用系統默認的索引,即從0開始的int。

axis=0時ignore_index=True,index采用系統默認索引:

>>> pd.concat([df1, df2], axis=0, ignore_index=True)
    A    B    C    D    E    F
0  1.0  1.0  1.0  1.0  NaN  NaN
1  1.0  1.0  1.0  1.0  NaN  NaN
2  1.0  1.0  1.0  1.0  NaN  NaN
3  1.0  1.0  1.0  1.0  NaN  NaN
4  NaN  NaN  2.0  2.0  2.0  2.0
5  NaN  NaN  2.0  2.0  2.0  2.0
6  NaN  NaN  2.0  2.0  2.0  2.0
7  NaN  NaN  2.0  2.0  2.0  2.0

 axis=1時ignore_index=True,columns采用系統默認索引:

>>> pd.concat([df1, df2], axis=1, ignore_index=True)
    0    1    2    3    4    5    6    7
1  1.0  1.0  1.0  1.0  NaN  NaN  NaN  NaN
2  1.0  1.0  1.0  1.0  NaN  NaN  NaN  NaN
3  1.0  1.0  1.0  1.0  2.0  2.0  2.0  2.0
4  1.0  1.0  1.0  1.0  2.0  2.0  2.0  2.0
5  NaN  NaN  NaN  NaN  2.0  2.0  2.0  2.0
6  NaN  NaN  NaN  NaN  2.0  2.0  2.0  2.0

 

1.5,keys

默認值:keys=None

可以加一層標簽,標識行/列名稱屬於原來哪個df。

axis=0時設置keys:

>>> pd.concat([df1, df2],  axis=0, keys=['x', 'y'])
      A    B    C    D    E    F
x 4  1.0  1.0  1.0  1.0  NaN  NaN
  3  1.0  1.0  1.0  1.0  NaN  NaN
  2  1.0  1.0  1.0  1.0  NaN  NaN
  1  1.0  1.0  1.0  1.0  NaN  NaN
y 6  NaN  NaN  2.0  2.0  2.0  2.0
  5  NaN  NaN  2.0  2.0  2.0  2.0
  4  NaN  NaN  2.0  2.0  2.0  2.0
  3  NaN  NaN  2.0  2.0  2.0  2.0

 axis=1時設置keys:

>>> pd.concat([df1, df2], axis=1, keys=['x', 'y'])
     x                   y               
     D    C    B    A    F    E    D    C
1  1.0  1.0  1.0  1.0  NaN  NaN  NaN  NaN
2  1.0  1.0  1.0  1.0  NaN  NaN  NaN  NaN
3  1.0  1.0  1.0  1.0  2.0  2.0  2.0  2.0
4  1.0  1.0  1.0  1.0  2.0  2.0  2.0  2.0
5  NaN  NaN  NaN  NaN  2.0  2.0  2.0  2.0
6  NaN  NaN  NaN  NaN  2.0  2.0  2.0  2.0 

也可以傳字典取代keys:

>>> pd.concat({'x': df1, 'y': df2}, axis=0)
      A    B    C    D    E    F
x 4  1.0  1.0  1.0  1.0  NaN  NaN
  3  1.0  1.0  1.0  1.0  NaN  NaN
  2  1.0  1.0  1.0  1.0  NaN  NaN
  1  1.0  1.0  1.0  1.0  NaN  NaN
y 6  NaN  NaN  2.0  2.0  2.0  2.0
  5  NaN  NaN  2.0  2.0  2.0  2.0
  4  NaN  NaN  2.0  2.0  2.0  2.0
  3  NaN  NaN  2.0  2.0  2.0  2.0

  

1.6,levels

默認值:levels=None

明確行/列名稱取值范圍:

>>> pd.concat([df1, df2], axis=0, keys=['x', 'y'], levels=[['x', 'y', 'z', 'w']])
>>> df.index.levels
[['x', 'y', 'z', 'w'], ['1', '2', '3', '4', '5', '6']]

 

1.7,sort

默認值:sort=True,提示新版本會設置默認為False,並取消該參數

但0.22.0中雖然取消了,還是設置為True

非合並方向的行/列名稱是否排序。例如1.1中默認axis=0時columns進行了排序,axis=1時index進行了排序。

axis=0時sort=False,columns不作排序:

>>> pd.concat([df1, df2], axis=0, sort=False)
    D    C    B    A    F    E
4  1.0  1.0  1.0  1.0  NaN  NaN
3  1.0  1.0  1.0  1.0  NaN  NaN
2  1.0  1.0  1.0  1.0  NaN  NaN
1  1.0  1.0  1.0  1.0  NaN  NaN
6  2.0  2.0  NaN  NaN  2.0  2.0
5  2.0  2.0  NaN  NaN  2.0  2.0
4  2.0  2.0  NaN  NaN  2.0  2.0
3  2.0  2.0  NaN  NaN  2.0  2.0

axis=1時sort=False,index不作排序:

>>> pd.concat([df1, df2], axis=1, sort=False)
    D    C    B    A    F    E    D    C
4  1.0  1.0  1.0  1.0  2.0  2.0  2.0  2.0
3  1.0  1.0  1.0  1.0  2.0  2.0  2.0  2.0
2  1.0  1.0  1.0  1.0  NaN  NaN  NaN  NaN
1  1.0  1.0  1.0  1.0  NaN  NaN  NaN  NaN
6  NaN  NaN  NaN  NaN  2.0  2.0  2.0  2.0
5  NaN  NaN  NaN  NaN  2.0  2.0  2.0  2.0

 

1.8,concat多個DataFrame

>>> pd.concat([df1, df2, df3], sort=False, join_axes=[df1.columns])
    D    C    B    A
4  1.0  1.0  1.0  1.0
3  1.0  1.0  1.0  1.0
2  1.0  1.0  1.0  1.0
1  1.0  1.0  1.0  1.0
6  2.0  2.0  NaN  NaN
5  2.0  2.0  NaN  NaN
4  2.0  2.0  NaN  NaN
3  2.0  2.0  NaN  NaN
6  NaN  NaN  3.0  3.0
5  NaN  NaN  3.0  3.0
2  NaN  NaN  3.0  3.0
1  NaN  NaN  3.0  3.0

  

2,append

append(self, other, ignore_index=False, verify_integrity=False)

豎方向合並df,沒有axis屬性

不會就地修改,而是會創建副本

示例:

>>> df1.append(df2)    # 相當於pd.concat([df1, df2])
    A    B    C    D    E    F
4  1.0  1.0  1.0  1.0  NaN  NaN
3  1.0  1.0  1.0  1.0  NaN  NaN
2  1.0  1.0  1.0  1.0  NaN  NaN
1  1.0  1.0  1.0  1.0  NaN  NaN
6  NaN  NaN  2.0  2.0  2.0  2.0
5  NaN  NaN  2.0  2.0  2.0  2.0
4  NaN  NaN  2.0  2.0  2.0  2.0
3  NaN  NaN  2.0  2.0  2.0  2.0  

  

2.1,ignore_index屬性

>>> df1.append(df2, ignore_index=True)
    A    B    C    D    E    F
0  1.0  1.0  1.0  1.0  NaN  NaN
1  1.0  1.0  1.0  1.0  NaN  NaN
2  1.0  1.0  1.0  1.0  NaN  NaN
3  1.0  1.0  1.0  1.0  NaN  NaN
4  NaN  NaN  2.0  2.0  2.0  2.0
5  NaN  NaN  2.0  2.0  2.0  2.0
6  NaN  NaN  2.0  2.0  2.0  2.0
7  NaN  NaN  2.0  2.0  2.0  2.0

 

2.2,append多個DataFrame

和concat相同,append也支持append多個DataFrame

>>> df1.append([df2, df3], ignore_index=True)
     A    B    C    D    E    F
0   1.0  1.0  1.0  1.0  NaN  NaN
1   1.0  1.0  1.0  1.0  NaN  NaN
2   1.0  1.0  1.0  1.0  NaN  NaN
3   1.0  1.0  1.0  1.0  NaN  NaN
4   NaN  NaN  2.0  2.0  2.0  2.0
5   NaN  NaN  2.0  2.0  2.0  2.0
6   NaN  NaN  2.0  2.0  2.0  2.0
7   NaN  NaN  2.0  2.0  2.0  2.0
8   3.0  3.0  NaN  NaN  3.0  3.0
9   3.0  3.0  NaN  NaN  3.0  3.0
10  3.0  3.0  NaN  NaN  3.0  3.0
11  3.0  3.0  NaN  NaN  3.0  3.0

  

3,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 = pd.DataFrame({'A': ['a0', 'a1', 'a2', 'a3'],
                         'B': ['b0', 'b1', 'b2', 'b3'],
                         'k1': ['x', 'x', 'y', 'y']})
>>> right = pd.DataFrame({'C': ['c1', 'c2', 'c3', 'c4'],
                          'D': ['d1', 'd2', 'd3', 'd4'],
                          'k1': ['y', 'y', 'z', 'z']})
>>> left
    A   B  k1
0  a0  b0  x
1  a1  b1  x
2  a2  b2  y
3  a3  b3  y
>>> right
    C   D  k1
0  c1  d1  y
1  c2  d2  y
2  c3  d3  z
3  c4  d4  z

對df1和df2進行merge:

>>> pd.merge(left, right)
    A   B  k1  C   D
0  a2  b2  y  c1  d1
1  a2  b2  y  c2  d2
2  a3  b3  y  c1  d1
3  a3  b3  y  c2  d2

可以看到只有df1和df2的key1=y的行保留了下來,即默認合並后只保留有共同列項並且值相等行(即交集)。

本例中left和right的k1=y分別有2個,最終構成了2*2=4行。

如果沒有共同列會報錯:

>>> del left['k1']
>>> pd.merge(left, right)
pandas.errors.MergeError: No common columns to perform merge on

 

3.1,on屬性

新增一個共同列,但沒有相等的值,發現合並返回是空列表,因為默認只保留所有共同列都相等的行:

>>> left['k2'] = list('1234')
>>> right['k2'] = list('5678')
>>> pd.merge(left, right)
Empty DataFrame
Columns: [B, A, k1, k2, F, E]
Index: []

可以指定on,設定合並基准列,就可以根據k1進行合並,並且left和right共同列k2會同時變換名稱后保留下來:

>>> pd.merge(left, right, on='k1')
    A   B  k1  k2_x   C   D   k2_y
0  a2  b2  y     3    c1  d1   5
1  a2  b2  y     3    c2  d2   6
2  a3  b3  y     4    c1  d1   5
3  a3  b3  y     4    c2  d2   6

默認值:on的默認值是所有共同列,本例為:on=['k1', 'k2']

 

3.2,how屬性

how取值范圍:'inner', 'outer', 'left', 'right'

默認值:how='inner'

‘inner’:共同列的值必須完全相等:

>>> pd.merge(left, right, on='k1', how='inner')
    A   B  k1  k2_x   C   D   k2_y
0  a2  b2  y     3    c1  d1   5
1  a2  b2  y     3    c2  d2   6
2  a3  b3  y     4    c1  d1   5
3  a3  b3  y     4    c2  d2   6

‘outer’:共同列的值都會保留,left或right在共同列上的差集,會對它們的缺失列項的值賦上NaN:

>>> pd.merge(left, right, on='k1', how='outer')
    A    B k1   k2_x  C    D  k2_y
0   a0   b0  x    1  NaN  NaN  NaN
1   a1   b1  x    2  NaN  NaN  NaN
2   a2   b2  y    3   c1   d1    5
3   a2   b2  y    3   c2   d2    6
4   a3   b3  y    4   c1   d1    5
5   a3   b3  y    4   c2   d2    6
6  NaN  NaN  z  NaN   c3   d3    7
7  NaN  NaN  z  NaN   c4   d4    8

‘left’:根據左邊的DataFrame確定共同列的保留值,右邊缺失列項的值賦上NaN:

pd.merge(left, right, on='k1', how='left')
    A   B k1  k2_x  C    D   k2_y
0  a0  b0  x    1  NaN  NaN  NaN
1  a1  b1  x    2  NaN  NaN  NaN
2  a2  b2  y    3   c1   d1    5
3  a2  b2  y    3   c2   d2    6
4  a3  b3  y    4   c1   d1    5
5  a3  b3  y    4   c2   d2    6

‘right’:根據右邊的DataFrame確定共同列的保留值,左邊缺失列項的值賦上NaN:

>>> pd.merge(left, right, on='k1', how='right')
     A    B k1  k2_x  C   D   k2_y
0   a2   b2  y    3  c1  d1    5
1   a3   b3  y    4  c1  d1    5
2   a2   b2  y    3  c2  d2    6
3   a3   b3  y    4  c2  d2    6
4  NaN  NaN  z  NaN  c3  d3    7
5  NaN  NaN  z  NaN  c4  d4    8

  

3.3,indicator

默認值:indicator=False,不顯示合並方式

設置True表示顯示合並方式,即left / right / both:

>>> pd.merge(left, right, on='k1', how='outer', indicator=True)
     A    B k1  k2_x  C    D   k2_y     _merge
0   a0   b0  x    1  NaN  NaN  NaN   left_only
1   a1   b1  x    2  NaN  NaN  NaN   left_only
2   a2   b2  y    3   c1   d1    5        both
3   a2   b2  y    3   c2   d2    6        both
4   a3   b3  y    4   c1   d1    5        both
5   a3   b3  y    4   c2   d2    6        both
6  NaN  NaN  z  NaN   c3   d3    7  right_only
7  NaN  NaN  z  NaN   c4   d4    8  right_only

  

歡迎轉載博客文章,轉載請標明出處!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM