SQL の join のように DataFrame を横方向につなげる場合、使用可能な関数(or メソッド)は3つあります。
- concat
- merge
- join
どれを使うかは結合キーをなににするかで変わります。データをキーにして結合したければ merge を使います。インデックスで結合したければ、動きは微妙に違いますが3つのうちどれでも使えます。
ちなみに、concat は縦方向の結合もできます。(ここでは触れませんが)
目次
インデックスで結合
データで結合
インデックス と データで結合
キー不一致(内部・外部結合)
列名が重複する場合
インデックスで結合
インデックスによる結合を、concat、merge、join で実行してみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
import pandas as pd from pandas import DataFrame df1=DataFrame([[1,2,3],[4,5,6],[7,8,9]], columns=['aa','bb','cc'], index=['AA','BB','CC']) df2=DataFrame([[100,200],[400,500],[700,800]], columns=['dd','ee'], index=['AA','BB','CC']) df1 #----------------- # aa bb cc # AA 1 2 3 # BB 4 5 6 # CC 7 8 9 #----------------- ↑ 結合キー df2 #----------------- # dd ee # AA 100 200 # BB 400 500 # CC 700 800 #----------------- ↑ 結合キー |
インデックスの AA、BB、CC が結合キーになります。
concat
1 2 3 4 5 6 7 |
pd.concat([df1, df2], axis=1) #------------------------------- # aa bb cc dd ee # AA 1 2 3 100 200 # BB 4 5 6 400 500 # CC 7 8 9 700 800 #------------------------------- |
merge
1 2 3 4 5 6 7 |
pd.merge(df1, df2, right_index=True, left_index=True) #------------------------------- # aa bb cc dd ee # AA 1 2 3 100 200 # BB 4 5 6 400 500 # CC 7 8 9 700 800 #------------------------------- |
join
1 2 3 4 5 6 7 |
df1.join([df2]) #------------------------------- # aa bb cc dd ee # AA 1 2 3 100 200 # BB 4 5 6 400 500 # CC 7 8 9 700 800 #------------------------------- |
3つとも同じ結果になりました。
データで結合
データ列で結合する場合は merge を使います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
df1=DataFrame([[1,2,'x'],[4,5,'y'],[7,8,'z']], columns=['aa','bb','KEY1'], index=['LA','LB','LC']) df2=DataFrame([[100,'x'],[400,'y'],[700,'z']], columns=['dd','KEY2'], index=['RA','RB','RC']) df1 #------------------ # aa bb KEY1 # LA 1 2 x # LB 4 5 y # LC 7 8 z #------------------ ↑ 結合キー df2 #------------------ # dd KEY2 # RA 100 x # RB 400 y # RC 700 z #------------------ ↑ 結合キー |
merge
結合キーは left_on、right_on で指定します。
1 2 3 4 5 6 7 |
pd.merge(df1, df2, left_on='KEY1', right_on='KEY2') #-------------------------- # aa bb KEY1 dd KEY2 # 0 1 2 x 100 x # 1 4 5 y 400 y # 2 7 8 z 700 z #-------------------------- |
-
左右の結合キーの名称が同じ場合は on で指定できます。
pd.merge(df1, df2, on='KEY') -
結合キーを指定しなくても、同一名称の列があれば python がキーに割り当ててくれます。
pd.merge(df1, df2)
インデックス と データで結合
インデックス と データ列で結合する場合も merge を使います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
df1=DataFrame([[1,2,3],[4,5,6],[7,8,9]], columns=['aa','bb','cc'], index=['AA','BB','CC']) df2=DataFrame([[100,'AA'],[400,'BB'],[700,'CC']], columns=['dd','KEY'], index=['XX','YY','ZZ']) df1 #---------------- # aa bb cc # AA 1 2 3 # BB 4 5 6 # CC 7 8 9 #---------------- ↑ 結合キー df2 #---------------- # dd KEY # XX 100 AA # YY 400 BB # ZZ 700 CC #---------------- ↑ 結合キー |
df1 のインデックス × df2 の KEY 列で結合します。
merge
1 2 3 4 5 6 7 |
pd.merge(df1, df2, left_index=True, right_on='KEY') #------------------------- # aa bb cc dd KEY # XX 1 2 3 100 AA # YY 4 5 6 400 BB # ZZ 7 8 9 700 CC #------------------------- |
キー不一致(内部・外部結合)
キーが一致しないケースではどのように結合されるでしょうか。SQL なら内部結合、外部結合で処理しますが、DataFrame でも同じことができるのでしょうか。
結論から言うとできます。内部結合も外部結合(左も右も)も可能です。
サンプルが長くなりますが、concat、merge、join それぞれのケースを確認してみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
df1=DataFrame([[1,2,3],[4,5,6],[7,8,9]], columns=['aa','bb','cc'], index=['AA','BB','CC']) df3=DataFrame([[100,200],[400,500]], columns=['dd','ee'], index=['AA','EE']) df1 #----------------- # aa bb cc # AA 1 2 3 # BB 4 5 6 # CC 7 8 9 #----------------- ↑ 結合キー df3 #----------------- # dd ee # AA 100 200 # EE 400 500 #----------------- ↑ 結合キー |
一致するキーは AA だけです。
concat
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# # 内部結合 pd.concat([df1, df3], axis=1, join='inner') #---------------------------- # aa bb cc dd ee # AA 1 2 3 100 200 #---------------------------- # # 外部結合 pd.concat([df1, df3], axis=1, join='outer') #---------------------------- # aa bb cc dd ee # AA 1 2 3 100 200 # BB 4 5 6 NaN NaN # CC 7 8 9 NaN NaN # EE NaN NaN NaN 400 500 #---------------------------- # # 左外部結合 pd.concat([df1, df3], axis=1, join_axes=[df1.index]) #---------------------------- # aa bb cc dd ee # AA 1 2 3 100 200 # BB 4 5 6 NaN NaN # CC 7 8 9 NaN NaN #---------------------------- # # 右外部結合 pd.concat([df1, df3], axis=1, join_axes=[df3.index]) #---------------------------- # aa bb cc dd ee # AA 1 2 3 100 200 # EE NaN NaN NaN 400 500 #---------------------------- |
merge
結合条件は how で指定します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# # 内部結合 pd.merge(df1, df3, right_index=True, left_index=True, how='inner') #---------------------------- # aa bb cc dd ee # AA 1 2 3 100 200 #---------------------------- # # 外部結合 pd.merge(df1, df3, right_index=True, left_index=True, how='outer') #---------------------------- # aa bb cc dd ee # AA 1 2 3 100 200 # BB 4 5 6 NaN NaN # CC 7 8 9 NaN NaN # EE NaN NaN NaN 400 500 #---------------------------- # # 左外部結合 pd.merge(df1, df3, right_index=True, left_index=True, how='left') #---------------------------- # aa bb cc dd ee # AA 1 2 3 100 200 # BB 4 5 6 NaN NaN # CC 7 8 9 NaN NaN #---------------------------- # # 右外部結合 pd.merge(df1, df3, right_index=True, left_index=True, how='right') #---------------------------- # aa bb cc dd ee # AA 1 2 3 100 200 # EE NaN NaN NaN 400 500 #---------------------------- |
join
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# # 内部結合 df1.join([df3], how='inner') #---------------------------- # aa bb cc dd ee # AA 1 2 3 100 200 #---------------------------- # # 外部結合 df1.join([df3], how='outer') #---------------------------- # aa bb cc dd ee # AA 1 2 3 100 200 # BB 4 5 6 NaN NaN # CC 7 8 9 NaN NaN # EE NaN NaN NaN 400 500 #---------------------------- # # 左外部結合 df1.join([df3], how='left') #---------------------------- # aa bb cc dd ee # AA 1 2 3 100 200 # BB 4 5 6 NaN NaN # CC 7 8 9 NaN NaN #---------------------------- # # 右外部結合 # right を指定できないので、df1 と df3 を入れ替えて left を指定 df3.join([df1], how='left') #---------------------------- # dd ee aa bb cc # AA 100 200 1 2 3 # EE 400 500 NaN NaN NaN #---------------------------- |
列名が重複する場合
列名が重複すると concat、merge、join で動作がそれぞれ異なります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
df1=DataFrame([[1,2,3],[4,5,6],[7,8,9]], columns=['aa','bb','cc'], index=['AA','BB','CC']) df4=DataFrame([[100,200],[400,500],[700,800]], columns=['aa','bb'], index=['AA','BB','CC']) df1 #---------------- # aa bb cc # AA 1 2 3 # BB 4 5 6 # CC 7 8 9 #---------------- df4 #---------------- # aa bb ← df1 と列名が重複 # AA 100 200 # BB 400 500 # CC 700 800 #---------------- |
concat
1 2 3 4 5 6 7 |
pd.concat([df1, df4], axis=1) #--------------------------- # aa bb cc aa bb # AA 1 2 3 100 200 # BB 4 5 6 400 500 # CC 7 8 9 700 800 #--------------------------- |
列名が重複したままくっつきました。
keys オプションを使って列を階層化することもできます。
➡ pd.concat([df1, df4], axis=1, keys=['L','R'])
merge
1 2 3 4 5 6 7 |
pd.merge(df1, df4, right_index=True, left_index=True) #--------------------------------- # aa_x bb_x cc aa_y bb_y # AA 1 2 3 100 200 # BB 4 5 6 400 500 # CC 7 8 9 700 800 #--------------------------------- |
列名に接尾辞 _x、_y がついて区別されました
join
1 2 3 4 |
df1.join([df4]) #----------------------------------------------------------- # ValueError: Indexes have overlapping values: ['aa', 'bb'] #----------------------------------------------------------- |
列名が重複するとエラーになります
One Response on “DataFrameを横方向に結合する concat、merge、join-python”