【解説】内部結合の方法を学ぶ | データサイエンス100本ノック【問36〜問37 回答】

【解説】内部結合の方法を学ぶ | データサイエンス100本ノック【問36〜問37 回答】

当ページのリンクには広告が含まれています。





目次

この記事の対象者


・ データサイエンティストを目指している人

・ Pythonで内部結合の設定方法を学びたい人

以降はデータサイエンス100本ノックの問題を題材に、内部結合の方法について学んでいきます。

データサイエンス100本ノックの始め方は、以下の記事を参考にしていただければと思います。

>>データサイエンス100本ノックの始め方

第36問目: 内部結合(共通カラムが1つ)

P-036: レシート明細データフレーム(df_receipt)と店舗データフレーム(df_store)を内部結合し、レシート明細データフレームの全項目と店舗データフレームの店舗名(store_name)を10件表示させよ。



表の「結合」といえばconcatを使えば良いのかな?

>>concatの復習をする



結論としては、concatではなくmergeを使います。

concatは、シンプルに2つの表を横方向または縦方向に連結させる関数です。

この問題は、「内部結合」という結合方式であり、concatのようなシンプルな連結ではありません。

内部結合とは、2つのデータフレームに共通するカラムが存在した場合、そのカラムの値を軸に結合する方式です。こういった結合を行う場合は、mergeという関数を使います。

>> 内部結合とは何かを詳しく学ぶ

実際に問題を解きながらmergeの使い方を学んでいきましょう。

まずは、問題で述べられているdf_receiptというデータフレームと、df_storeというデータフレームを出力し、共通するカラムの存在を確認しましょう。

まずは、df_receiptから出力します。

1
df_receipt
出力
1
2
3
4
5
6
	sales_ymd	sales_epoch	store_cd	receipt_no	receipt_sub_no	customer_id	product_cd	quantity	amount
0 20181103 1541203200 S14006 112 1 CS006214000001 P070305012 1 158
1 20181118 1542499200 S13008 1132 2 CS008415000097 P070701017 1 81
2 20170712 1499817600 S14028 1102 1 CS028414000014 P060101005 1 170
3 20190205 1549324800 S14042 1132 1 ZZ000000000000 P050301001 1 25
4 20180821 1534809600 S14025 1102 2 CS025415000050 P060102007 1 90

次に、df_storeを出力します。カラム名だけ把握できれば良いので、head()を付与します。

1
df_store.head()
出力
1
2
3
4
5
6
7

store_cd store_name prefecture_cd prefecture address address_kana tel_no longitude latitude floor_area
0 S12014 千草台店 12 千葉県 千葉県千葉市稲毛区千草台一丁目 チバケンチバシイナゲクチグサダイイッチョウメ 043-123-4003 140.1180 35.63559 1698.0
1 S13002 国分寺店 13 東京都 東京都国分寺市本多二丁目 トウキョウトコクブンジシホンダニチョウメ 042-123-4008 139.4802 35.70566 1735.0
2 S14010 菊名店 14 神奈川県 神奈川県横浜市港北区菊名一丁目 カナガワケンヨコハマシコウホククキクナイッチョウメ 045-123-4032 139.6326 35.50049 1732.0
3 S14033 阿久和店 14 神奈川県 神奈川県横浜市瀬谷区阿久和西一丁目 カナガワケンヨコハマシセヤクアクワニシイッチョウメ 045-123-4043 139.4961 35.45918 1495.0
4 S14036 相模原中央店 14 神奈川県 神奈川県相模原市中央二丁目 カナガワケンサガミハラシチュウオウニチョウメ 042-123-4045 139.3716 35.57327 1679.0

共通のカラムは、store_cdが目視で確認できます。



共通のカラムは、目視で確認しないといけないの?カラムがたくさん存在したら確認するの大変だよね?



共通のカラムを機械的に抽出する方法もあります。その方法については本記事の後半でまとめたいと思います。

共通のカラムがstore_cdであることが分かったので、早速merge関数を用いて内部結合していきます。

回答であるコードを先に記述した上で、merge関数の使い方を解説します。

回答
1
pd.merge(df_receipt, df_store[['store_cd', 'store_name']], how='inner', on='store_cd').head(10)

merge関数の第1引数と第2引数は、結合するデータフレームを指定します。

問題文よりdf_receiptに対してdf_storeを内部結合しdf_receiptの全項目とdf_storeの店舗名(store_name)を10件表示させたいので、第2引数には、df_storeから共通カラムであるstore_cdstore_nameのみを抽出したデータフレームを結合する対象として指定します。

第3引数のhowは、結合方法を指定します。

howで指定できる結合方法は以下のとおりです。

  • inner: 内部結合
  • left: 左結合
  • right: 右結合
  • outer: 完全外部結合

今回は内部結合なので、how='inner'とします。

第4引数のonは、共通するカラム名を指定します。

結合する2つのデータフレームに共通するカラムは、store_cdなので、on='store_cd'とします。

回答のコードを実行すると以下のような出力が得られ、正常に内部結合がされていることが確認できます。

出力
1
2
3
4
5
6
7
8
9
10
11
  sales_ymd sales_epoch store_cd  receipt_no  receipt_sub_no  customer_id product_cd  quantity  amount  store_name
0 20181103 1541203200 S14006 112 1 CS006214000001 P070305012 1 158 葛が谷店
1 20181116 1542326400 S14006 112 2 ZZ000000000000 P080401001 1 48 葛が谷店
2 20170118 1484697600 S14006 1162 1 CS006815000006 P050406035 1 220 葛が谷店
3 20190524 1558656000 S14006 1192 1 CS006514000034 P060104003 1 80 葛が谷店
4 20190419 1555632000 S14006 112 2 ZZ000000000000 P060501002 1 148 葛が谷店
5 20181119 1542585600 S14006 1152 2 ZZ000000000000 P050701001 1 88 葛が谷店
6 20171211 1512950400 S14006 1132 2 CS006515000175 P090903001 1 80 葛が谷店
7 20191021 1571616000 S14006 1112 2 CS006415000221 P040602001 1 405 葛が谷店
8 20170710 1499644800 S14006 1132 2 CS006411000036 P090301051 1 330 葛が谷店
9 20190805 1564963200 S14006 112 1 CS006211000012 P050104001 1 115 葛が谷店

第37問目: 内部結合(共通カラムが複数)

P-037: 商品データフレーム(df_product)とカテゴリデータフレーム(df_category)を内部結合し、商品データフレームの全項目とカテゴリデータフレームの小区分名(category_small_name)を10件表示させよ。

この問題もmerge関数を用いて2つのデータフレームを内部結合します。

内部結合をするために、まずは2つのデータフレームにおいて共通する絡むを把握します。

2つのデータフレームそれぞれを出力します。

まずは、df_productです。

1
df_product
出力
1
2
3
4
5
6
7
8
9
10
11
12
13
14

product_cd category_major_cd category_medium_cd category_small_cd unit_price unit_cost
0 P040101001 04 0401 040101 198.0 149.0
1 P040101002 04 0401 040101 218.0 164.0
2 P040101003 04 0401 040101 230.0 173.0
3 P040101004 04 0401 040101 248.0 186.0
4 P040101005 04 0401 040101 268.0 201.0
... ... ... ... ... ... ...
10025 P091503001 09 0915 091503 280.0 210.0
10026 P091503002 09 0915 091503 680.0 510.0
10027 P091503003 09 0915 091503 1080.0 810.0
10028 P091503004 09 0915 091503 1130.0 848.0
10029 P091503005 09 0915 091503 1280.0 960.0
10030 rows × 6 columns

続いて、df_categoryです。

1
df_category
出力
1
2
3
4
5
6
7
8
9
10
11
12
13
  category_major_cd category_major_name category_medium_cd  category_medium_name  category_small_cd category_small_name
0 04 惣菜 0401 御飯類 040101 弁当類
1 04 惣菜 0401 御飯類 040102 寿司類
2 04 惣菜 0402 佃煮類 040201 魚介佃煮類
3 04 惣菜 0402 佃煮類 040202 海草佃煮類
4 04 惣菜 0402 佃煮類 040203 野菜佃煮類
... ... ... ... ... ... ...
223 09 洗剤 0914 ペットフード 091401 ペットフード
224 09 洗剤 0914 ペットフード 091402 ペット用剤
225 09 洗剤 0914 ペットフード 091403 ペット用具
226 09 洗剤 0915 DIY用品 091501 建築・塗装材料
227 09 洗剤 0915 DIY用品 091503 園芸用品
228 rows × 6 columns

さて、共通するカラムは何でしょうか?

目視で共通するカラムを抽出するのは少し厳しいですよね。

ここからは共通するカラムをpythonを使って抽出する方法をまとめたいと思います。

2つのデータフレームにおける共通カラムの抽出方法



大まかな流れは以下です。


1. 各データフレームのカラムデータのみを抽出

2. 各カラムデータの重複値のみを抽出して出力する
1. 各データフレームのカラムデータのみを抽出


まずは、各データフレームのカラムデータのみを抽出します。

データフレームのカラムデータの抽出は、columnsメソッドを使うことで簡単に抽出できます。

まずはdf_productからカラムデータを抽出し、df_product_columnsという変数に代入します。

1
2
df_product_columns = df_product.columns
df_product_columns
出力
1
2
3
Index(['product_cd', 'category_major_cd', 'category_medium_cd',
'category_small_cd', 'unit_price', 'unit_cost'],
dtype='object')

では、もう一方のデータフレームであるdf_categoryについても同様に、カラムデータを抽出し、df_category_columnsという変数に代入します。

1
2
df_category_columns = df_category.columns
df_category_columns
出力
1
2
3
Index(['category_major_cd', 'category_major_name', 'category_medium_cd',
'category_medium_name', 'category_small_cd', 'category_small_name'],
dtype='object')

これで各データフレームのカラムデータのみの抽出が完了しました。

2. 各カラムデータの重複値のみを抽出して出力する


各カラムデータは配列として抽出されています。

2つの配列データから共通のデータを抽出するにはsetを使います。

1
2
df_and = set(df_product_columns) & set(df_category_columns)
df_and
出力
1
{'category_major_cd', 'category_medium_cd', 'category_small_cd'}

各カラムデータの重複値が出力されました。

つまり、本問題で内部結合をする上で考慮が必要な共通するカラムデータは、category_major_cd, category_medium_cd, category_small_cdの3つであることが分かりました。

早速mergeメソッドを用いて、df_productに対して、df_categoryの共通カラム3つとcategory_small_cdを抽出したデータフレームを内部結合します。

1
2
3
pd.merge(df_product
, df_category[['category_major_cd', 'category_medium_cd','category_small_cd','category_small_name']]
, how='inner', on=['category_major_cd', 'category_medium_cd','category_small_cd']).head(10)
出力
1
2
3
4
5
6
7
8
9
10
11
  product_cd  category_major_cd category_medium_cd  category_small_cd unit_price  unit_cost category_small_name
0 P040101001 04 0401 040101 198.0 149.0 弁当類
1 P040101002 04 0401 040101 218.0 164.0 弁当類
2 P040101003 04 0401 040101 230.0 173.0 弁当類
3 P040101004 04 0401 040101 248.0 186.0 弁当類
4 P040101005 04 0401 040101 268.0 201.0 弁当類
5 P040101006 04 0401 040101 298.0 224.0 弁当類
6 P040101007 04 0401 040101 338.0 254.0 弁当類
7 P040101008 04 0401 040101 420.0 315.0 弁当類
8 P040101009 04 0401 040101 498.0 374.0 弁当類
9 P040101010 04 0401 040101 580.0 435.0 弁当類

これで完了です。



まとめ: 内部結合の方法を学びました。

本記事は、【Python】内部結合の方法を学ぶ | データサイエンス100本ノック【問36〜問37 回答】というテーマでまとめました。

内部結合のポイントは、共通カラムを把握することです。

本記事では共通カラムを抽出する方法も合わせて紹介しました。

>> 続きはこちら

コメント