pandas DataFrame 結合 append index merge join

python

pandasでDataFrameのデータを結合する方法

2020年5月22日

こんにちは。

 

産婦人科医で人工知能の研究をしているTommy(Twitter:@obgyntommy)です。

 

本記事ではPythonのライブラリの1つである pandas でDataFrameを結合する方法について学習していきます。

 

pandasの使い方については、以下の記事に基本から応用までを網羅してまとめていますので参考にしてください。

 

関連記事
Python pandas 使い方
【Python】Pandasの使い方【基本から応用まで全て解説】

続きを見る

 

本記事の目標はpandasのDataFrameを結合する方法を完全にマスターする事です。

 

データを処理するときには、色々なデータリソースから取得することがあります。

 

その際に、複数の分かれているデータは、処理がしづらいので、1つにまとめる事が多々あります。

 

この様にpandasを用いてDaataFrameのデータを1つに結合する方法について理解していきましょう。

 

本記事でpandasのDataFrameのデータを結合する方法を習得しつつ、自由自在にデータを扱えるようになりましょう。

 

PandasのData Frame の概要と作成方法・変換方法についての記事は、以下になりますので参考にして頂ければ知識がまとまるかと思います。

 

関連記事
Python pandas DataFrame 概要 作成方法 変換方法
【Python】pandas.DataFrameの概要と作成方法・変換方法

続きを見る

 

ここで本記事の学習到達目標です。

 

 本記事の学習目標

  • データの結合する種類の理解
  • データを縦方向に結合する方法の理解(append,  concatメソッドを利用)
  • データを横方向に結合する方法の種類の理解(内部結合、左外部からの結合、右外部からの結合、完全外部からの結合)
  • データを横方向に結合する際に利用するメソッド(merge, joinメソッド)の理解

 

では早速、学習していきましょう。

 

データの結合の種類について

pandas DataFrame 結合 append index merge join

データの結合の種類について説明します。

 

データの結合は縦、横方向があり、columns (列名)や index (行名)などをキー値として結合します。

 

下記表のように、いくつか種類があります。

 

よく、ベン図を用いて説明もされるので、結合イメージと一緒にベン図を表にしたものが下記になります。

 

種類説明イメージベン図
縦方向縦方向にデータを結合します。
列名が一致している場合、列名が一部一致していない場合があります。
pandas DataFrame 結合 append index merge join 縦方向にデータを結合しているイメージ図。列名が一致している場合、一部一致していない場合が あることも示している。pandas DataFrame 結合 append index merge join 縦方向にデータを結合しているベン図のイメージ図。列名が一致している場合、一部一致していない場合があることもベン図で示している。
横方向

内部結合

結合するキー値を元に、お互い一致するデータ(右図の場合だと2, 3列)を残します。pandas DataFrame 結合 append index merge join 横方向に内部結合するキー値を元に、お互い一致するデータを残している図pandas DataFrame 結合 append index merge join 横方向に内部結合するキー値を元に、お互い一致するデータを残している事を示しているベン図
横方向

左外部結合

結合するキー値を元に、左側に一致するデータを残します。
右側にデータがない場合は、NaNとなる。
pandas DataFrame 結合 append index merge join 横方向に左外部結合する図。キー値を元に左側に一致するデータを残している。右側にデータがない場合はNaNとなる事を表している。pandas DataFrame 結合 append index merge join 横方向に左外部結合している事を示しているベン図。キー値を元に左側に一致するデータを残している事も示している。右側にデータがない場合はNaNとなる事をベン図で表している。
横方向

右外部結合

結合するキー値を元に、右側に一致するデータを残します。
左側にデータがない場合は、NaNとなる。
pandas DataFrame 結合 append index merge join  横方向の右外部から結合している図。結合するキー値を元に右側に一致するデータを残している。左側にデータがない場合はNaNと事も示している。pandas DataFrame 結合 append index merge join  横方向の右外部から結合している事を示しているベン図。結合するキー値を元に右側に一致するデータを残している様子も表されている。左側にデータがない場合はNaNと事もベン図で分かる様に示している。
横方向

完全外部結合

結合するキー値を元に、

お互い一致するデータも一致しないデータも残します。

左が一致しない場合、左がNaN、
右が一致しない場合、右がNaN となります。

pandas DataFrame 結合 append index merge join 横方向に完全外部から結合しているイメージ。結合するキー値を元にお互い一致するデータも一致しないデータも残している様子を示している。pandas DataFrame 結合 append index merge join 横方向に完全外部から結合しているイメージを表しているベン図。結合するキー値を元にお互い一致するデータも一致しないデータも残している様子をベン図でも示している。

 

この時点では大まかに、結合の種類そのイメージを掴む事ができれば十分です。

これから、各々の結合の種類について詳しくコードを用いて解説していきます。

tommy とみー
Tommy

 

縦方向に結合する方法|append(), concat()

pandas DataFrame 結合 append index merge join

 

縦方向の連結には、append()concat() メソッドを使います。

 

以下が縦方向の連結のイメージ図です。

pandas DataFrame 結合 append index merge join 縦方向にデータを結合しているイメージ図。列名が一致している場合、一部一致していない場合が あることも示している。

pandas.DataFrame.append の公式メソッドは以下を参照して下さい。

 

 

pandas.concat の公式メソッドは以下を参照して下さい。

 

pandas.concat — pandas 2.2.3 documentation
pandas.concat — pandas 2.2.3 documentation

続きを見る

 

 

  • append新しい行を追加するメソッド
  • concatcolumns(列名)や index (行名)を参照して結合するメソッド

 

使用するデータ

理解しやすいように、データ数の少ないデータを用意しましたので、それを使いましょう。

 

内容は、商品の購入リストが複数あるデータです。

 

  • purchase1 は商品ID、個数、購入者のラベル
  • purchase2 も商品ID、個数、購入者のラベル
  • purchase3 は商品ID、個数、顧客IDのラベル

 

この様に、purchase1, 2 は「商品ID」、「個数」「購入者」です。

 

purchase3 は「購入者」ではなく、「顧客ID」でデータが保存されてています。

 

In[]

 

Out[]

purchase1,purchase2,purchase3に分けて、すぐ上のコードの結果を表した表。商品ID、個数、購入者のラベルを各々示している。

 

append()メソッド

データを結合する方法としてappend()メソッドを使用しましょう。

 

append は正確には DataFrame.append です。これは DataFrame のメソッドになります。

 

DataFrame.append の公式ドキュメントは以下になります。

 

 

なので、purchase1 などのDataFrame型の後につけて、引数に、結合したDataFrameを渡します。

 

列のラベルが同じ場合のデータ結合の仕方

purchase1,purchase2,purchase3に分けて、表した表。purchase1,purchase2では商品ID、個数、購入者のラベルを示している。purchase3では商品ID、個数、顧客IDのラベルを示している。

purchase1purchase2 のデータを使用して、列のラベルが同じ場合のデータの結合の仕方について確認してみましょう。

 

In[]

 

Out[]

purchase1のDataFrame型のデータにpurchase2のデータをつけて、次のコード purchase12 = purchase1.append(purchase2) purchase12.head(8)  で出力した表のうちの8行。

 

DataFrame の index が、上図の左端の様に 0, 1, 2, 3, 0, 1, 2, 3 となっているのを連番にする場合は、パラメータを ignore_index=True とします。

 

ignore_indexTrue にすることで、0, 1, 2, 3, 0, 1, 2, 3 となっているのを、再度数値の連番で割り当て、0, 1, 2, 3, 4,.. としてくれます。

 

In[]

 

列のラベルが一部異なる場合の結合の仕方

purchase1,purchase2,purchase3に分けて、すぐ上のコードの結果を表した表。商品ID、個数、購入者のラベルを各々示している。

purchase1purchase3 を使用して列のラベルが1部異なる場合の結合の仕方について確認しましょう。

 

列の過不足が DataFrame 間にあっても append() メソッドの使い方は同じです。

 

どちらかのデータに列が不足している場合は、NaN が割り当てられます。

 

In[]

 

Out[]

列の過不足がDataFrame間にある場合の結合した方法。過不足が列にNaNが割り当てられた。以下のコードで出力した結果。 purchase13 = purchase1.append(purchase3) # データ表示 purchase13.head(8)

 

concat()メソッド

次に、concat() メソッドを使ってみましょう。

 

concat() は pandasのメソッドになります。

 

import pandas as pd で pandasをpdと定義しているので、pd の後につけて、pd.concat() と使います。

 

引数に結合する DataFrame を list型で渡します。

 

列のラベルが同じ場合の結合の仕方

purchase1,purchase2,purchase3に分けて、すぐ上のコードの結果を表した表。商品ID、個数、購入者のラベルを各々示している。

concat を使って、purchage1purchage2 の結合をしてみましょう。

 

In[]

 

append() メソッドと同じ結果になりますね。

 

列の値が一部違う場合の結合の仕方について

purchase1,purchase2,purchase3に分けて、すぐ上のコードの結果を表した表。商品ID、個数、購入者のラベルを各々示している。

purchase1purchase3 の結合をしてみましょう。

 

In[]

 

こちらもappend() メソッドと同じ結果ですね。

 

横方向のデータの結合の方法について

pandas DataFrame 結合 append index merge join

横方向の結合ではconcat()merge()join()メソッドを使います。

 

各々のメソッドの違いについては、以下の様になります。

 

  • concatcolumns (列名)や index (行名)を参照して結合するメソッド
  • mergeキー列を指定して結合するメソッド。index をキーとすることも可能。
  • joinindex(行名)をキーとして結合するメソッド

 

concat でも結合はできますが、結合するキーが複数 :1 や、相互に対応するキーがない 0:1 がある複雑な結合がではエラーが出ます。

 

以下の様なイメージです。

pandas DataFrame 結合  concatでも結合はできますが、結合するキーが複数:1や、相互に対応するキーがない0:1がある複雑な結合がではエラーが出る事を示している図。

その為、mergejoin について説明していきます。

 

join は 下記図のように、キーにしたい列を index にする必要があります。また、必要に応じて index から戻したりと、少しメンドウですよね。

pandas DataFrame 結合 join の解説。キーにしたい列を index にする必要があり、また必要に応じて index から戻したりする必要がある事を示した図。そこでおすすめのメソッドは、merge()メソッドです。

 

merge() はキーにしたい列を指定して結合できます。

 

index() にするしないを気にせずに結合でき、コード量少なくすむメリットがあるので、おすすめのメソッドです。

 

pandas.contact() メソッドの公式ドキュメントは以下になりますので、参考にして下さい。

 

pandas.concat — pandas 2.2.3 documentation
pandas.concat — pandas 2.2.3 documentation

続きを見る

 

pandas.DataFrame.merge() メソッドの公式ドキュメントは以下になりますので、参考にして下さい。

 

pandas.DataFrame.merge — pandas 2.2.3 documentation
pandas.DataFrame.merge — pandas 2.2.3 documentation

続きを見る

 

pandas.DataFrame.join() メソッドの公式ドキュメントは以下になりますので、参考にして下さい。

 

pandas.DataFrame.join — pandas 2.2.3 documentation
pandas.DataFrame.join — pandas 2.2.3 documentation

続きを見る

 

 

使用するデータ

理解しやすいように、データ数の少ない用意したデータを使います。

 

商品の購入リスト(商品ID、個数など)、顧客リスト(購入者)、商品リスト(商品ID)があるイメージです。

 

In[]

 

Out[]

列の過不足がDataFrame間にある場合の結合した方法。過不足が列にNaNが割り当てられた。以下のコードで出力した結果。 purchase13 = purchase1.append(purchase3) # データ表示 purchase13.head(8)

 

indexの設定

join()メソッドはDataFrameの index をキーに結合するメソッドです。

 

これから、列を index にする方法やリセットする方法について解説していきます。

 

index は DataFrame の構成要素の行名のようなものです。

joinメソッドの使用法の解説をする為の、index、colums、dataの関係図を表した表。

 

set_index()メソッド

列の過不足がDataFrame間にある場合の結合した方法。過不足が列にNaNが割り当てられた。以下のコードで出力した結果。 purchase13 = purchase1.append(purchase3) # データ表示 purchase13.head(8)

今のデータでは、index0, 1, 2,  3… と連番が入っています。

 

これをキーにして結合したいわけではないので、set_index() メソッドで、indexを変更します。

 

pandas.DataFrame.set_index() メソッドについての公式ドキュメントは以下になります。

 

pandas.DataFrame.set_index — pandas 2.2.3 documentation
pandas.DataFrame.set_index — pandas 2.2.3 documentation

続きを見る

 

例えば、purchase  データの「商品ID」の列を  index とする場合は、下記コードを実行します。

 

In[]

 

Out[]

purchaseデータの「商品ID」の列をindexと下場合の表。列には個数、購入者の項目、行には商品IDを記載している。

 

reset_index() メソッド

indexを列データから、数値に戻す場合はreset_indexメソッドを使います。

 

pandas.DataFrame.reset_index() の公式メソッドは以下になります。

 

pandas.DataFrame.reset_index — pandas 2.2.3 documentation
pandas.DataFrame.reset_index — pandas 2.2.3 documentation

続きを見る

 

In[]

 

内部結合

内部結合は、二つのデータを指定されたキーで結びつける時、それぞれ存在するデータのみを残します。

pandas DataFrame 結合 append index merge join 横方向に内部結合するキー値を元に、お互い一致するデータを残している図

purchaseproduct の「商品ID」をキーにして結合していきましょう。

 

次のように結合をして、購入リストにも「商品名」、「価格」が含まれるデータを目指します。

purchaseとproductの「商品ID」をキーにして結合いた結合結果を示している表。購入リストにも「商品名」、「価格」が含まれるデータになっている。

 

merge() メソッド

merge() メソッドはDataFrameのメソッドなので、DataFrameの後ろにくっ付けて使います。

 

結合ではデータを左右に並べて、表現します。

 

下記のコードの様に、メソッドを実行するDataFrameを左のデータ、引数で渡すデータを右のデータとして扱います。

mergeはDataFrameのメソッドなので、DataFrameの後ろにつけて使い、結合ではデータを左右に並べて表現するが、メソッドを実行するDataFrameを左のデータ、引数で渡すデータを右のデータとして扱う事を、コードを用いて説明している図。

パラメータは次のように設定します。

 

パラメータの suffixes は今回は使いませんが、 suffixes は結合するデータ同士に同じ列名があると、結合後同じ列が2つできてしまいます。

 

その為、列名に _x  や _y の文字をつけて同じ列になることを防止します。

 

パラメータ備考
howinnnerinnner: 内部結合(初期値)
left:左外部結合
right:右外部結合
outer:完全外部結合
left_on商品IDメソッドを実行するDataFrameのキー列
right_on商品ID引数で渡すDataFrameのキー列
suffixes無し左右のデータで重複した列名があったときに
追加する文字列。
tupleで左右の文字列を指定。
初期値(‘ _x ’ , ‘ _y ’)

 

それでは、コードを動かしてみましょう。

 

purchase() のメソッドとして実行します。

 

In[]

 

Out[]

Pythonで、以下のコードの結果、作成された表。 # 結合 new_purchase = purchase.merge(product, how='inner', left_on='商品ID', right_on='商品ID') # データ確認 new_purchase.head()

きちんと結合できているのが分かりますね。

 

left_onright_on は今回のように同じ列名で結合する場合は、省略する事も可能です。

 

初期値が inner なので、how も省略できますが、分かり易さのためにパラメータで指示しておくのが良いでしょう。

 

省略したコードは下記になります。

 

In[]

 

join()メソッド

join() はDataFrameのメソッドなので、DataFrameの後ろにつけて使います。

 

パラメータは次のようにします。

 

パラメータの  lsuffixrsuffixmergesuffixes と同じ役割です。今回は使いません。

 

パラメータ備考
howinnnerinnner: 内部結合
left:左外部結合(初期値)
right:右外部結合
outer:完全外部結合
lsuffix無し左右のデータで重複した列名があったときに
左のデータの列に追加する文字
rsuffix無し左右のデータで重複した列名があったときに
右のデータの列に追加する文字

 

コードを動かしてみましょう。

 

purchase() のメソッドとして実行します。

 

In[]

 

Out[]

Pythonで以下のコードを実行した結果、得られた表。 # キー列をindexにする prchase_temp = purchase.set_index('商品ID') product_temp = product.set_index('商品ID') # 結合 new_purchase = prchase_temp.join(product_temp, how='inner') # データ確認 new_purchase.head()

商品IDをキーに、うまく結合できました。

 

reset_indexindex を数値に戻します。

 

In[]

 

Out[]

Pythonで以下のコードを実行下結果、得られた表。 # indexを数値にする new_purchase = new_purchase.reset_index() # データ確認 new_purchase.head()

 

左外部結合

左外部結合は、二つのデータを指定されたキーで結びつける時、左のデータは全て残し、右の該当するデータのみを結合します。

 

以下がイメージ図です。

pandas DataFrame 結合 append index merge join 横方向に左外部結合する図。キー値を元に左側に一致するデータを残している。右側にデータがない場合はNaNとなる事を表している。先ほど作った、new_purchasecustomer の「購入者」「顧客名」をキーにして結合していきましょう。

 

次のように結合して、「顧客ID」が含まれるデータを目指します。

 

購入者のゲストの箇所は、IDがなく空欄になります。

 

new_purchaseとcustomerの「購入者」「顧客名」をキーにして結合していく方法。 結合して、「顧客ID」が含まれるデータの作成を行っている様子を描いている。 購入者のゲストの箇所は、IDがなく空欄になっている。

各メソッド同じ結果を作っているので、ここからはパラメータとコードを紹介していきます。

 

merge()メソッド

次のパラメータとコードを使います。

 

パラメータ備考
howleftinnner: 内部結合(初期値)
left:左外部結合
right:右外部結合
outer:完全外部結合
left_on購入者メソッドを実行するDataFrameのキー列
right_on顧客名引数で渡すDataFrameのキー列
suffixes無し左右のデータで重複した列名があったときに
追加する文字列。
tupleで左右の文字列を指定。
初期値(‘_x’, ‘_y’)

 

In[]

 

Out[]

Pythonで以下のコードを実行した結果 # 結合 new_purchase2 = new_purchase.merge(customer, how='left', left_on='購入者', right_on='顧客名') # データ確認 new_purchase2.head()

 

結合列名がそれぞれ違うと、それぞれの列が残るため、「顧客名」列は drop() メソッドで削除します。

 

pandas.DataFrame.drop() の公式メソッドは以下になりますので、参考にして下さい。

 

pandas.DataFrame.drop — pandas 2.2.3 documentation
pandas.DataFrame.drop — pandas 2.2.3 documentation

続きを見る

 

In[]

 

join()メソッド

次のパラメータとコードを使います。

 

パラメータ備考
howleftinnner: 内部結合
left:左外部結合(初期値)
right:右外部結合
outer:完全外部結合
lsuffix無し左右のデータで重複した列名があったときに
左のデータの列に追加する文字
rsuffix無し左右のデータで重複した列名があったときに
右のデータの列に追加する文字

 

In[]

 

Out[]

Pythonで以下のコードを実行した結果の表。 # キー列をindexにする new_purchase_temp = new_purchase.set_index('購入者') customer_temp = customer.set_index('顧客名') # 結合 new_purchase2 = new_purchase_temp.join(customer_temp, how='left') # indexを数値化 new_purchase2 = new_purchase2.reset_index() # データ確認 new_purchase2.head()

違う列名で結合した場合、reset_index したときに列名が「index」となってしまうので、rename()メソッドを使って、列名を変更します。

 

pandas.DataFrame.rename() についての公式メソッドについては以下の公式ドキュメントを参考にして下さい。

 

pandas.DataFrame.rename — pandas 2.2.3 documentation
pandas.DataFrame.rename — pandas 2.2.3 documentation

続きを見る

 

In[]

 

右外部結合

右外部結合は、二つのデータを指定されたキーで結びつける時、右のデータは全て残し、左の該当するデータのみを結合します。

 

以下の図でイメージを表します。

pandas DataFrame 結合 append index merge join  横方向の右外部から結合している図。結合するキー値を元に右側に一致するデータを残している。左側にデータがない場合はNaNと事も示している。やっていることは、左外部結合が逆になっただけなので、同じことをデータ入れ替えて行います。

 

mergejoin を実行する DataFrame が new_purchase から customer に変えています。

右外部からの結合を表している図。結合した結果、mergeやjoinを実行するDataFrameがnew_purchaseからcustomerに変えている様子が分かる。

 

merge()メソッド

次のパラメータとコードを使います。

 

 

パラメータ備考
howrightinnner: 内部結合(初期値)
left:左外部結合
right:右外部結合
outer:完全外部結合
left_on顧客名メソッドを実行するDataFrameのキー列
right_on購入者引数で渡すDataFrameのキー列
suffixes無し左右のデータで重複した列名があったときに
追加する文字列。
tupleで左右の文字列を指定。
初期値(‘_x’, ‘_y’)

 

In[]

 

join()メソッド

 

パラメータ備考
howrightinnner: 内部結合
left:左外部結合(初期値)
right:右外部結合
outer:完全外部結合
lsuffix無し左右のデータで重複した列名があったときに
左のデータの列に追加する文字
rsuffix無し左右のデータで重複した列名があったときに
右のデータの列に追加する文字

 

In[]

 

完全外部結合

完全外部結合は左右のデータをそれぞれ残しつつ、結合します。

pandas DataFrame 結合 append index merge join 横方向に完全外部から結合しているイメージ。結合するキー値を元にお互い一致するデータも一致しないデータも残している様子を示している。

今回のデータでは適切な例ではないですが、new_purchasecustomer の「購入者」「顧客名」をキーにして結合していきましょう。

 

new_purchaseとcustomerの「購入者」「顧客名」をキーにして結合した模式図

 

merge()メソッド

次のパラメータとコードを使います。

 

パラメータ備考
howouterinnner: 内部結合(初期値)
left:左外部結合
right:右外部結合
outer:完全外部結合
left_on購入者メソッドを実行するDataFrameのキー列
right_on顧客名引数で渡すDataFrameのキー列
suffixes無し左右のデータで重複した列名があったときに
追加する文字列。
tupleで左右の文字列を指定。
初期値(‘_x’, ‘_y’)

 

In[]

 

join

次のパラメータとコードを使います。

 

パラメータ備考
howrightinnner: 内部結合
left:左外部結合(初期値)
right:右外部結合
outer:完全外部結合
lsuffix無し左右のデータで重複した列名があったときに
左のデータの列に追加する文字
rsuffix無し左右のデータで重複した列名があったときに
右のデータの列に追加する文字

 

In[]

 

joinindex にしてから結合するので、merge と違って、購入者、顧客名の両方の列が残らない違いがあります。

 

Pythonで以下のコードで出力した表。 # キー列をindexにする new_purchase_temp = new_purchase.set_index('購入者') customer_temp = customer.set_index('顧客名') # 結合 new_purchase2 = customer_temp.join(new_purchase_temp, how='outer') # indexを数値化 new_purchase2 = new_purchase2.reset_index() # 列名を変更 new_purchase2 = new_purchase2.rename(columns={'index': '購入者'}) # データ確認 new_purchase2.head(7)

 

 

今回は以上となります。

 

pandas の使用方法については以下の記事にまとめています。

 

本記事で pandas でDataFrameの結合方法を行う学習が出来た方は再度復習してみましょう。

 

関連記事
Python pandas 使い方
【Python】Pandasの使い方【基本から応用まで全て解説】

続きを見る

 

また、PandasのDataFrameについての詳しい記事は、以下の記事にまとめていますので参照してください。

 

関連記事
Python pandas DataFrame 概要 作成方法 変換方法
【Python】pandas.DataFrameの概要と作成方法・変換方法

続きを見る

 

 

 

人気記事 【入門から上級レベルまで】人工知能・機械学習の独学におすすめの本25選

人気記事 無料あり:機械学習エンジニアの僕がおすすめするAI(機械学習)特化型プログラミングスクール3社


-python
-, ,

Copyright© Tommy blog  , 2024 All Rights Reserved.