pandas(合并concat和merge)

pandas处理多组数据的时候往往会要用到数据的合并处理,其中有三种方式,concat、append和merge。

1、concat

concat是一种基本的合并方式。而且concat中有很多参数可以调整,合并成你想要的数据形式。axis来指明合并方向。axis=0是预设值,因此未设定任何参数时,函数默认axis=0。(0表示上下合并,1表示左右合并)


 
 
  1. import pandas as pd
  2. import numpy as np
  3. #定义资料集
  4. df1 = pd.DataFrame(np.ones(( 3, 4))* 0, columns=[ 'a', 'b', 'c', 'd'])
  5. df2 = pd.DataFrame(np.ones(( 3, 4))* 1, columns=[ 'a', 'b', 'c', 'd'])
  6. df3 = pd.DataFrame(np.ones(( 3, 4))* 2, columns=[ 'a', 'b', 'c', 'd'])
  7. #concat纵向合并
  8. res = pd.concat([df1, df2, df3], axis= 0)
  9. #打印结果
  10. print(res)
  11. '''
  12. a b c d
  13. 0 0.0 0.0 0.0 0.0
  14. 1 0.0 0.0 0.0 0.0
  15. 2 0.0 0.0 0.0 0.0
  16. 0 1.0 1.0 1.0 1.0
  17. 1 1.0 1.0 1.0 1.0
  18. 2 1.0 1.0 1.0 1.0
  19. 0 2.0 2.0 2.0 2.0
  20. 1 2.0 2.0 2.0 2.0
  21. 2 2.0 2.0 2.0 2.0
  22. '''

上述index为0,1,2,0,1,2形式。为什么会出现这样的情况,其实是仍然按照合并前的index组合起来的。若希望递增,请看下面示例:

ignore_index (重置 index)

重置后的index为0,1,……8


 
 
  1. res = pd.concat([df1, df2, df3], axis= 0, ignore_index= True) # 将ignore_index设置为True
  2. print(res) #打印结果
  3. '''
  4. a b c d
  5. 0 0.0 0.0 0.0 0.0
  6. 1 0.0 0.0 0.0 0.0
  7. 2 0.0 0.0 0.0 0.0
  8. 3 1.0 1.0 1.0 1.0
  9. 4 1.0 1.0 1.0 1.0
  10. 5 1.0 1.0 1.0 1.0
  11. 6 2.0 2.0 2.0 2.0
  12. 7 2.0 2.0 2.0 2.0
  13. 8 2.0 2.0 2.0 2.0
  14. '''

join (合并方式)

join='outer'为预设值,因此未设定任何参数时,函数默认join='outer'。此方式是依照column来做纵向合并,有相同的column上下合并在一起,其他独自的column个自成列,原本没有值的位置皆以NaN填充。


 
 
  1. import pandas as pd
  2. import numpy as np
  3. #定义资料集
  4. df1 = pd.DataFrame(np.ones(( 3, 4))* 0, columns=[ 'a', 'b', 'c', 'd'], index=[ 1, 2, 3])
  5. df2 = pd.DataFrame(np.ones(( 3, 4))* 1, columns=[ 'b', 'c', 'd', 'e'], index=[ 2, 3, 4])
  6. res = pd.concat([df1, df2], axis= 0, join= 'outer') #纵向"外"合并df1与df2
  7. print(res)
  8. '''
  9. a b c d e
  10. 1 0.0 0.0 0.0 0.0 NaN
  11. 2 0.0 0.0 0.0 0.0 NaN
  12. 3 0.0 0.0 0.0 0.0 NaN
  13. 2 NaN 1.0 1.0 1.0 1.0
  14. 3 NaN 1.0 1.0 1.0 1.0
  15. 4 NaN 1.0 1.0 1.0 1.0
  16. '''
  17. res = pd.concat([df1, df2], axis= 0, join= 'inner') #纵向"内"合并df1与df2
  18. #打印结果
  19. print(res)
  20. '''
  21. b c d
  22. 1 0.0 0.0 0.0
  23. 2 0.0 0.0 0.0
  24. 3 0.0 0.0 0.0
  25. 2 1.0 1.0 1.0
  26. 3 1.0 1.0 1.0
  27. 4 1.0 1.0 1.0
  28. '''

join_axes (依照 axes 合并)


 
 
  1. import pandas as pd
  2. import numpy as np
  3. #定义资料集
  4. df1 = pd.DataFrame(np.ones(( 3, 4))* 0, columns=[ 'a', 'b', 'c', 'd'], index=[ 1, 2, 3])
  5. df2 = pd.DataFrame(np.ones(( 3, 4))* 1, columns=[ 'b', 'c', 'd', 'e'], index=[ 2, 3, 4])
  6. #依照`df1.index`进行横向合并
  7. res = pd.concat([df1, df2], axis= 1, join_axes=[df1.index])
  8. #打印结果
  9. print(res)
  10. # a b c d b c d e
  11. # 1 0.0 0.0 0.0 0.0 NaN NaN NaN NaN
  12. # 2 0.0 0.0 0.0 0.0 1.0 1.0 1.0 1.0
  13. # 3 0.0 0.0 0.0 0.0 1.0 1.0 1.0 1.0

上述脚本中,join_axes=[df1.index]表明按照df1的index来合并,可以看到结果中去掉了df2中出现但df1中没有的index=4这一行。

2、append (添加数据) 

append只有纵向合并,没有横向合并。


 
 
  1. import pandas as pd
  2. import numpy as np
  3. #定义资料集
  4. df1 = pd.DataFrame(np.ones(( 3, 4))* 0, columns=[ 'a', 'b', 'c', 'd'])
  5. df2 = pd.DataFrame(np.ones(( 3, 4))* 1, columns=[ 'a', 'b', 'c', 'd'])
  6. df3 = pd.DataFrame(np.ones(( 3, 4))* 1, columns=[ 'a', 'b', 'c', 'd'])
  7. s1 = pd.Series([ 1, 2, 3, 4], index=[ 'a', 'b', 'c', 'd'])
  8. #将df2合并到df1的下面,以及重置index,并打印出结果
  9. res = df1.append(df2, ignore_index= True)
  10. print(res)
  11. # a b c d
  12. # 0 0.0 0.0 0.0 0.0
  13. # 1 0.0 0.0 0.0 0.0
  14. # 2 0.0 0.0 0.0 0.0
  15. # 3 1.0 1.0 1.0 1.0
  16. # 4 1.0 1.0 1.0 1.0
  17. # 5 1.0 1.0 1.0 1.0
  18. #合并多个df,将df2与df3合并至df1的下面,以及重置index,并打印出结果
  19. res = df1.append([df2, df3], ignore_index= True)
  20. print(res)
  21. # a b c d
  22. # 0 0.0 0.0 0.0 0.0
  23. # 1 0.0 0.0 0.0 0.0
  24. # 2 0.0 0.0 0.0 0.0
  25. # 3 1.0 1.0 1.0 1.0
  26. # 4 1.0 1.0 1.0 1.0
  27. # 5 1.0 1.0 1.0 1.0
  28. # 6 1.0 1.0 1.0 1.0
  29. # 7 1.0 1.0 1.0 1.0
  30. # 8 1.0 1.0 1.0 1.0
  31. #合并series,将s1合并至df1,以及重置index,并打印出结果
  32. res = df1.append(s1, ignore_index= True)
  33. print(res)
  34. # a b c d
  35. # 0 0.0 0.0 0.0 0.0
  36. # 1 0.0 0.0 0.0 0.0
  37. # 2 0.0 0.0 0.0 0.0
  38. # 3 1.0 2.0 3.0 4.0

3、merge

根据两组数据中的关键字key来合并(key在两组数据中是完全一致的)。

3.1依据一组key合并


 
 
  1. import pandas as pd
  2. #定义资料集并打印出
  3. left = pd.DataFrame({ 'key': [ 'K0', 'K1', 'K2', 'K3'],
  4. 'A': [ 'A0', 'A1', 'A2', 'A3'],
  5. 'B': [ 'B0', 'B1', 'B2', 'B3']})
  6. right = pd.DataFrame({ 'key': [ 'K0', 'K1', 'K2', 'K3'],
  7. 'C': [ 'C0', 'C1', 'C2', 'C3'],
  8. 'D': [ 'D0', 'D1', 'D2', 'D3']})
  9. print(left)
  10. # A B key
  11. # 0 A0 B0 K0
  12. # 1 A1 B1 K1
  13. # 2 A2 B2 K2
  14. # 3 A3 B3 K3
  15. print(right)
  16. # C D key
  17. # 0 C0 D0 K0
  18. # 1 C1 D1 K1
  19. # 2 C2 D2 K2
  20. # 3 C3 D3 K3
  21. #依据key column合并,并打印出
  22. res = pd.merge(left, right, on= 'key')
  23. print(res)
  24. A B key C D
  25. # 0 A0 B0 K0 C0 D0
  26. # 1 A1 B1 K1 C1 D1
  27. # 2 A2 B2 K2 C2 D2
  28. # 3 A3 B3 K3 C3 D3

3.2 根据两组key合并

合并时有4种方法how = ['left', 'right', 'outer', 'inner'],预设值how='inner'

  • inner:按照关键字组合之后,去掉组合中有合并项为NaN的行。
  • outer :保留所有组合
  • left:仅保留左边合并项为NaN的行
  • right:仅保留右边合并项为NaN的行

 
 
  1. import pandas as pd
  2. import numpy as np
  3. #定义资料集并打印出
  4. left = pd.DataFrame({ 'key1': [ 'K0', 'K0', 'K1', 'K2'],
  5. 'key2': [ 'K0', 'K1', 'K0', 'K1'],
  6. 'A': [ 'A0', 'A1', 'A2', 'A3'],
  7. 'B': [ 'B0', 'B1', 'B2', 'B3']})
  8. right = pd.DataFrame({ 'key1': [ 'K0', 'K1', 'K1', 'K2'],
  9. 'key2': [ 'K0', 'K0', 'K0', 'K0'],
  10. 'C': [ 'C0', 'C1', 'C2', 'C3'],
  11. 'D': [ 'D0', 'D1', 'D2', 'D3']})
  12. print(left)
  13. '''
  14. key1 key2 A B
  15. 0 K0 K0 A0 B0
  16. 1 K0 K1 A1 B1
  17. 2 K1 K0 A2 B2
  18. 3 K2 K1 A3 B3
  19. '''
  20. print(right)
  21. '''
  22. key1 key2 C D
  23. 0 K0 K0 C0 D0
  24. 1 K1 K0 C1 D1
  25. 2 K1 K0 C2 D2
  26. 3 K2 K0 C3 D3
  27. '''
  28. #依据key1与key2 columns进行合并,并打印出四种结果['left', 'right', 'outer', 'inner']
  29. res = pd.merge(left, right, on=[ 'key1', 'key2'], how= 'inner')
  30. print(res)
  31. '''
  32. key1 key2 A B C D
  33. 0 K0 K0 A0 B0 C0 D0
  34. 1 K1 K0 A2 B2 C1 D1
  35. 2 K1 K0 A2 B2 C2 D2
  36. '''
  37. res = pd.merge(left, right, on=[ 'key1', 'key2'], how= 'outer')
  38. print(res)
  39. '''
  40. key1 key2 A B C D
  41. 0 K0 K0 A0 B0 C0 D0
  42. 1 K0 K1 A1 B1 NaN NaN
  43. 2 K1 K0 A2 B2 C1 D1
  44. 3 K1 K0 A2 B2 C2 D2
  45. 4 K2 K1 A3 B3 NaN NaN
  46. 5 K2 K0 NaN NaN C3 D3
  47. '''
  48. res = pd.merge(left, right, on=[ 'key1', 'key2'], how= 'left')
  49. print(res)
  50. '''
  51. key1 key2 A B C D
  52. 0 K0 K0 A0 B0 C0 D0
  53. 1 K0 K1 A1 B1 NaN NaN
  54. 2 K1 K0 A2 B2 C1 D1
  55. 3 K1 K0 A2 B2 C2 D2
  56. 4 K2 K1 A3 B3 NaN NaN
  57. '''
  58. res = pd.merge(left, right, on=[ 'key1', 'key2'], how= 'right')
  59. print(res)
  60. '''
  61. key1 key2 A B C D
  62. 0 K0 K0 A0 B0 C0 D0
  63. 1 K1 K0 A2 B2 C1 D1
  64. 2 K1 K0 A2 B2 C2 D2
  65. 3 K2 K0 NaN NaN C3 D3
  66. '''

3.3 Indicator

indicator=True会将合并的记录放在新的一列。


 
 
  1. import pandas as pd
  2. #定义资料集并打印出
  3. df1 = pd.DataFrame({ 'col1':[ 0, 1], 'col_left':[ 'a', 'b']})
  4. df2 = pd.DataFrame({ 'col1':[ 1, 2, 2], 'col_right':[ 2, 2, 2]})
  5. print(df1)
  6. # col1 col_left
  7. # 0 0 a
  8. # 1 1 b
  9. print(df2)
  10. # col1 col_right
  11. # 0 1 2
  12. # 1 2 2
  13. # 2 2 2
  14. # 依据col1进行合并,并启用indicator=True,最后打印出
  15. res = pd.merge(df1, df2, on= 'col1', how= 'outer', indicator= True)
  16. print(res)
  17. # col1 col_left col_right _merge
  18. # 0 0.0 a NaN left_only
  19. # 1 1.0 b 2.0 both
  20. # 2 2.0 NaN 2.0 right_only
  21. # 3 2.0 NaN 2.0 right_only
  22. # 自定indicator column的名称,并打印出
  23. res = pd.merge(df1, df2, on= 'col1', how= 'outer', indicator= 'indicator_column')
  24. print(res)
  25. # col1 col_left col_right indicator_column
  26. # 0 0.0 a NaN left_only
  27. # 1 1.0 b 2.0 both
  28. # 2 2.0 NaN 2.0 right_only
  29. # 3 2.0 NaN 2.0 right_only

3.4 依据index合并


 
 
  1. import pandas as pd
  2. #定义资料集并打印出
  3. left = pd.DataFrame({ 'A': [ 'A0', 'A1', 'A2'],
  4. 'B': [ 'B0', 'B1', 'B2']},
  5. index=[ 'K0', 'K1', 'K2'])
  6. right = pd.DataFrame({ 'C': [ 'C0', 'C2', 'C3'],
  7. 'D': [ 'D0', 'D2', 'D3']},
  8. index=[ 'K0', 'K2', 'K3'])
  9. print(left)
  10. # A B
  11. # K0 A0 B0
  12. # K1 A1 B1
  13. # K2 A2 B2
  14. print(right)
  15. # C D
  16. # K0 C0 D0
  17. # K2 C2 D2
  18. # K3 C3 D3
  19. #依据左右资料集的index进行合并,how='outer',并打印出
  20. res = pd.merge(left, right, left_index= True, right_index= True, how= 'outer')
  21. print(res)
  22. # A B C D
  23. # K0 A0 B0 C0 D0
  24. # K1 A1 B1 NaN NaN
  25. # K2 A2 B2 C2 D2
  26. # K3 NaN NaN C3 D3
  27. #依据左右资料集的index进行合并,how='inner',并打印出
  28. res = pd.merge(left, right, left_index= True, right_index= True, how= 'inner')
  29. print(res)
  30. # A B C D
  31. # K0 A0 B0 C0 D0
  32. # K2 A2 B2 C2 D2

3.5 解决overlapping的问题

下面脚本中,boys和girls均有属性age,但是两者值不同,因此需要在合并时加上后缀suffixes,以示区分。

 
 
  1. import pandas as pd
  2. #定义资料集
  3. boys = pd.DataFrame({ 'k': [ 'K0', 'K1', 'K2'], 'age': [ 1, 2, 3]})
  4. girls = pd.DataFrame({ 'k': [ 'K0', 'K0', 'K3'], 'age': [ 4, 5, 6]})
  5. #使用suffixes解决overlapping的问题
  6. res = pd.merge(boys, girls, on= 'k', suffixes=[ '_boy', '_girl'], how= 'inner')
  7. print(res)
  8. # age_boy k age_girl
  9. # 0 1 K0 4
  10. # 1 1 K0 5

以上是pandas中有关于合并的一些操作。当然,如果练习的多了,几个方法也是大同小异。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值