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

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

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




目次

この記事の対象者


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

・ Pythonで外部結合の方法を学びたい人

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


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


>>データサイエンス100本ノックの始め方を確認する


第38問目: 左外部結合

P-038: 顧客データフレーム(df_customer)とレシート明細データフレーム(df_receipt)から、各顧客ごとの売上金額合計を求めよ。ただし、買い物の実績がない顧客については売上金額を0として表示させること。また、顧客は性別コード(gender_cd)が女性(1)であるものを対象とし、非会員(顧客IDが’Z’から始まるもの)は除外すること。なお、結果は10件だけ表示させれば良い。



「各顧客ごと」のデータだからgroupbyメソッドを使うんだね!


そのとおり!この問題ではgroupby()メソッドを使います。


groupby()の使い方を忘れてしまった方は、以下の記事を参照してください。


>>groupby()メソッドの使い方を復習する


また2つのデータフレームを結合して各顧客ごとの売上金額合計を求めることになるので、merge()メソッドも活用することが想定されます


そして最終的に出力すべきカラムは、customer_idと各customer_id毎の売上金額合計の2カラムです。


このように、最終的な出力を意識しながら問題を解いていきましょう。


df_customerについては、いくつか条件が指定されているの後回しにします。


まずはdf_receiptにおいてgroupby()メソッドを用いて、各顧客ごとの売上金額の合計を表示します。


表示の仕方は2通りあります。どちらでも構いません。


パタン1
1
2
df_amount_sum1 = df_receipt.groupby('customer_id').agg({'amount':'sum'}).reset_index()
df_amount_sum1


パタン1の出力
1
2
3
4
5
6
7
8
9
10
11
12
13
	customer_id	amount
0 CS001113000004 1298
1 CS001114000005 626
2 CS001115000010 3044
3 CS001205000004 1988
4 CS001205000006 3337
... ... ...
8302 CS051513000004 551
8303 CS051515000002 265
8304 CS052212000002 192
8305 CS052514000001 178
8306 ZZ000000000000 12395003
8307 rows × 2 columns


パタン2
1
2
df_amount_sum2 = df_receipt.groupby('customer_id').amount.sum().reset_index()
df_amount_sum2


パタン2の出力
1
2
3
4
5
6
7
8
9
10
11
12
13
	customer_id	amount
0 CS001113000004 1298
1 CS001114000005 626
2 CS001115000010 3044
3 CS001205000004 1988
4 CS001205000006 3337
... ... ...
8302 CS051513000004 551
8303 CS051515000002 265
8304 CS052212000002 192
8305 CS052514000001 178
8306 ZZ000000000000 12395003
8307 rows × 2 columns


次に、df_customerにおいて、性別コードであるgender_cdが女性(1)であるレコードだけを抽出し、非会員(顧客IDが”Z”からはじまるもの)を除外します。


条件を満たしたレコードを抽出するには、query()メソッドを使います。


>>queryメソッドの使い方を復習する


性別コードが1のみを抽出し非会員を除外
1
2
df_tmp = df_customer.query('gender_cd == "1" and not customer_id.str.startswith("Z")', engine='python')
df_tmp


出力
1
2
3
4
5
6
7
8
9
10
11
12
13
  customer_id customer_name gender_cd gender  birth_day age postal_cd address application_store_cd  application_date  status_cd
0 CS021313000114 大野 あや子 1 女性 1981-04-29 37 259-1113 神奈川県伊勢原市粟窪********** S14021 20150905 0-00000000-0
2 CS031415000172 宇多田 貴美子 1 女性 1976-10-04 42 151-0053 東京都渋谷区代々木********** S13031 20150529 D-20100325-C
3 CS028811000001 堀井 かおり 1 女性 1933-03-27 86 245-0016 神奈川県横浜市泉区和泉町********** S14028 20160115 0-00000000-0
4 CS001215000145 田崎 美紀 1 女性 1995-03-29 24 144-0055 東京都大田区仲六郷********** S13001 20170605 6-20090929-2
6 CS015414000103 奥野 陽子 1 女性 1977-08-09 41 136-0073 東京都江東区北砂********** S13015 20150722 B-20100609-B
... ... ... ... ... ... ... ... ... ... ... ...
21965 CS042513000030 三宅 ヒカル 1 女性 1959-01-19 60 231-0865 神奈川県横浜市中区北方町********** S14042 20181114 0-00000000-0
21966 CS002512000474 市村 夏希 1 女性 1959-10-12 59 185-0034 東京都国分寺市光町********** S13002 20171110 0-00000000-0
21967 CS029414000065 上村 怜奈 1 女性 1970-10-19 48 279-0043 千葉県浦安市富士見********** S12029 20150313 F-20101028-F
21969 CS033512000184 池谷 華子 1 女性 1964-06-05 54 245-0016 神奈川県横浜市泉区和泉町********** S14033 20160206 0-00000000-0
21970 CS009213000022 稲垣 咲 1 女性 1996-08-16 22 154-0012 東京都世田谷区駒沢********** S13009 20150424 0-00000000-0
17918 rows × 11 columns


最後に内部結合を行います。customer_iddf_amount_sum1データフレームを左内部結合を行います。


>>内部結合と外部結合を学びたい方はこちら


>>mergeメソッドの使い方を復習する


df_tmpのcustomer_idカラムに対してdf_amount_sum1を左内部結合
1
pd.merge(df_tmp['customer_id'], df_amount_sum1, how='left', on='customer_id').fillna(0).head(10)


出力
1
2
3
4
5
6
7
8
9
10
11
  customer_id amount
0 CS021313000114 0.0
1 CS031415000172 5088.0
2 CS028811000001 0.0
3 CS001215000145 875.0
4 CS015414000103 3122.0
5 CS033513000180 868.0
6 CS035614000014 0.0
7 CS011215000048 3444.0
8 CS009413000079 0.0
9 CS040412000191 210.0


第39問目: 完全外部結合

P-039: レシート明細データフレーム(df_receipt)から売上日数の多い顧客の上位20件と、売上金額合計の多い顧客の上位20件を抽出し、完全外部結合せよ。ただし、非会員(顧客IDが’Z’から始まるもの)は除外すること。


まずはdf_receiptがどんなデータフレームか確認してみます。


1
df_receipt


出力
1
2
3
4
5
6
7
8
9
10
11
12
13
  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
... ... ... ... ... ... ... ... ... ...
104676 20180221 1519171200 S13043 1132 2 ZZ000000000000 P050101001 1 40
104677 20190911 1568160000 S14047 1132 2 ZZ000000000000 P071006005 1 218
104678 20170311 1489190400 S14040 1122 1 CS040513000195 P050405003 1 168
104679 20170331 1490918400 S13002 1142 1 CS002513000049 P060303001 1 148
104680 20190423 1555977600 S13016 1102 2 ZZ000000000000 P050601001 1 138
104681 rows × 9 columns


どういった処理が必要なのかを明確にするために、まずは特定の顧客IDを指定して、どのようなデータフレーム構造になっているかを確認します。


1
df_receipt.query('customer_id == "CS001113000004"')


出力
1
2
3
4

sales_ymd sales_epoch store_cd receipt_no receipt_sub_no customer_id product_cd quantity amount
31349 20190308 1552003200 S13001 112 1 CS001113000004 P071001012 1 98
35811 20190308 1552003200 S13001 112 2 CS001113000004 P071401009 1 1200


上記の出力をみてみると、20190308という日付で、1人の客CS001113000004の情報が2つ表示されていますね。


CS001113000004という顧客の売上日数は、本来は2019年3月8日の1回のみなのですが、現状のデータフレームのままだと2回とカウントされてしまいます。


CS001113000004という顧客は20190308という日時に1回の買い物をしたことにしないといけません。


そのため、上記のような情報は、2行ではなく1行にまとめなければなりません。



重複した行を抽出するにはどうすれば良いだろう?


重複した行を抽出するにはduplicated()メソッドを使えばOKです。


duplicated()メソッドを使うと重複した行をTrueで返却します。


duplicated()引数に何も指定しない場合は、データフレームのすべての列の要素が一致しているときに重複行であるとみなされます。


duplicated()メソッドの引数としてsubsetがあります。


subsetを用いて重複を判定する列を指定することが出来ます。


subsetは、リストで複数の列を指定することが可能です。


指定した全ての列の要素が一致しているときに重複したとみなし、Trueを返却します。


ここでは、重複していないデータのみを抽出したデータフレームを作成し、完全外部結合させたいので、論理否定演算子である~を用いて、重複していない場合Trueを返すようにします。


1
2
df_sales_ymd = df_receipt[~df_receipt.duplicated(subset=['customer_id', 'sales_ymd'])]
df_sales_ymd


出力
1
2
3
4
5
6
7
8
9
10
11
12
13
  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
... ... ... ... ... ... ... ... ... ...
103599 20180701 1530403200 S14023 1102 1 CS023514000014 P060702014 1 108
103694 20170714 1499990400 S14028 1152 1 CS028514000011 P090404005 1 288
103699 20190109 1546992000 S13016 1182 2 CS016515000072 P070202006 1 138
103818 20180521 1526860800 S12030 1182 2 CS030415000050 P090403001 1 248
104294 20170809 1502236800 S14024 1142 1 CS024415000002 P060303001 1 148
33445 rows × 9 columns


customer_idsales_ymd両方の要素の重複を除いたレシート明細データフレーム(df_sales_ymd)を取得することができました。


df_sales_ymdにおいて顧客ごとの売上日数の合計を求めたいので、groupby()メソッドを使います。groupby()メソッドの引数には、customer_idを指定し、売上日のカウントはsales_ymd.count()で算出します。


また、この処理をする際にindexが消滅してしまうので、reset_indexを用いてindexを付与します。


>>reset_indexメソッドの使い方を復習したい人はこちら


1
2
df_sales_ymd = df_sales_ymd.groupby('customer_id').sales_ymd.count().reset_index()
df_sales_ymd


出力
1
2
3
4
5
6
7
8
9
10
11
12
13
  customer_id sales_ymd
0 CS001113000004 1
1 CS001114000005 2
2 CS001115000010 3
3 CS001205000004 5
4 CS001205000006 6
... ... ...
8302 CS051513000004 1
8303 CS051515000002 1
8304 CS052212000002 1
8305 CS052514000001 1
8306 ZZ000000000000 1034
8307 rows × 2 columns


次に、顧客IDをが”Z”から始まるものを除外していきます。


特定の条件を満たしたレコードを抽出して処理を施すメソッドはquery()メソッドでしたね。


文字列の前方一致は、カラム名.str.startswith('文字列')とすることで、特定の文字列で始まる行のみを抽出できます。


>>文字列の前方一致について復習する


1
2
df_sales_ymd = df_sales_ymd.query('not customer_id.str.startswith("Z")', engine='python')
df_sales_ymd


1
2
3
4
5
6
7
8
9
10
11
12
13
  customer_id sales_ymd
0 CS001113000004 1
1 CS001114000005 2
2 CS001115000010 3
3 CS001205000004 5
4 CS001205000006 6
... ... ...
8301 CS051212000001 1
8302 CS051513000004 1
8303 CS051515000002 1
8304 CS052212000002 1
8305 CS052514000001 1
8306 rows × 2 columns


上位20件を表示するために降順でソートします。


>>ソートの方法を復習する


1
2
df_sales_ymd = df_sales_ymd.sort_values('sales_ymd', ascending=False).head(20)
df_sales_ymd


出力
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
  customer_id sales_ymd
7986 CS040214000008 23
3488 CS015415000185 22
2429 CS010214000010 22
2428 CS010214000002 21
5908 CS028415000007 21
3899 CS017415000097 20
3682 CS016415000141 20
6502 CS031414000051 19
3225 CS014214000023 19
4883 CS022515000226 19
4716 CS021515000172 19
7881 CS039414000052 19
4693 CS021514000045 19
4865 CS022515000028 18
6254 CS030214000008 18
4703 CS021515000056 18
3299 CS014415000077 18
4720 CS021515000211 18
6747 CS032415000209 18
6505 CS031414000073 18


最後に、作成した2つのデータフレームを完全外部結合すれば完成です。


1
pd.merge(df_sum, df_sales_ymd, how='outer', on='customer_id')


出力
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
customer_id amount  sales_ymd
0 CS017415000097 23086.0 20.0
1 CS015415000185 20153.0 22.0
2 CS031414000051 19202.0 19.0
3 CS028415000007 19127.0 21.0
4 CS001605000009 18925.0 NaN
5 CS010214000010 18585.0 22.0
6 CS016415000141 18372.0 20.0
7 CS006515000023 18372.0 NaN
8 CS011414000106 18338.0 NaN
9 CS038415000104 17847.0 NaN
10 CS035414000024 17615.0 NaN
11 CS021515000089 17580.0 NaN
12 CS032414000072 16563.0 NaN
13 CS016415000101 16348.0 NaN
14 CS011415000006 16094.0 NaN
15 CS034415000047 16083.0 NaN
16 CS007514000094 15735.0 NaN
17 CS009414000059 15492.0 NaN
18 CS030415000034 15468.0 NaN
19 CS015515000034 15300.0 NaN
20 CS040214000008 NaN 23.0
21 CS010214000002 NaN 21.0
22 CS014214000023 NaN 19.0
23 CS022515000226 NaN 19.0
24 CS021515000172 NaN 19.0
25 CS039414000052 NaN 19.0
26 CS021514000045 NaN 19.0
27 CS022515000028 NaN 18.0
28 CS030214000008 NaN 18.0
29 CS021515000056 NaN 18.0
30 CS014415000077 NaN 18.0
31 CS021515000211 NaN 18.0
32 CS032415000209 NaN 18.0
33 CS031414000073 NaN 18.0

第40問目: クロス結合

P-040: 全ての店舗と全ての商品を組み合わせると何件のデータとなるか調査したい。店舗(df_store)と商品(df_product)を直積した件数を計算せよ。


まずは、df_storedf_productを確認しましょう。


まずはdf_storeです。


1
df_store


出力
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
43
44
45
46
47
48
49
50
51
52
53
54
  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
5 S13051 板橋大原店 13 東京都 東京都板橋区大原町 トウキョウトイタバシクオオハラチョウ 03-0123-4029 139.6980 35.76788 1045.0
6 S13015 南砂店 13 東京都 東京都江東区南砂二丁目 トウキョウトコウトウクミナミスナニチョウメ 03-0123-4014 139.8229 35.67066 1337.0
7 S14040 長津田店 14 神奈川県 神奈川県横浜市緑区長津田みなみ台五丁目 カナガワケンヨコハマシミドリクナガツタミナミダイゴチョウメ 045-123-4046 139.4994 35.52398 1548.0
8 S13044 南六郷店 13 東京都 東京都大田区南六郷二丁目 トウキョウトオオタクミナミロクゴウニチョウメ 03-0123-4028 139.7207 35.54604 1379.0
9 S14050 阿久和西店 14 神奈川県 神奈川県横浜市瀬谷区阿久和西一丁目 カナガワケンヨコハマシセヤクアクワニシイッチョウメ 045-123-4053 139.4961 35.45918 1830.0
10 S13019 小茂根店 13 東京都 東京都板橋区小茂根一丁目 トウキョウトイタバシクコモネイッチョウメ 03-0123-4018 139.6795 35.74468 1004.0
11 S13052 森野店 13 東京都 東京都町田市森野三丁目 トウキョウトマチダシモリノサンチョウメ 042-123-4030 139.4383 35.55293 1087.0
12 S14028 二ツ橋店 14 神奈川県 神奈川県横浜市瀬谷区二ツ橋町 カナガワケンヨコハマシセヤクフタツバシチョウ 045-123-4042 139.4963 35.46304 1574.0
13 S13031 初台店 13 東京都 東京都渋谷区初台二丁目 トウキョウトシブヤクハツダイニチョウメ 03-0123-4020 139.6862 35.67616 986.0
14 S13038 東葛西店 13 東京都 東京都江戸川区東葛西九丁目 トウキョウトエドガワクヒガシカサイキュウチョウメ 03-0123-4024 139.8826 35.65366 1184.0
15 S13001 仲六郷店 13 東京都 東京都大田区仲六郷二丁目 トウキョウトオオタクナカロクゴウニチョウメ 03-1234-4007 139.7132 35.55135 1796.0
16 S14012 本牧和田店 14 神奈川県 神奈川県横浜市中区本牧和田 カナガワケンヨコハマシナカクホンモクワダ 045-123-4034 139.6582 35.42156 1341.0
17 S13004 鷺宮店 13 東京都 東京都中野区鷺宮三丁目 トウキョウトナカノクサギノミヤサンチョウメ 03-0123-4010 139.6421 35.72348 947.0
18 S14046 北山田店 14 神奈川県 神奈川県横浜市都筑区北山田一丁目 カナガワケンヨコハマシツヅキクキタヤマタイッチョウメ 045-123-4049 139.5916 35.56189 831.0
19 S14022 逗子店 14 神奈川県 神奈川県逗子市逗子一丁目 カナガワケンズシシズシイッチョウメ 046-123-4036 139.5789 35.29642 1838.0
20 S14011 日吉本町店 14 神奈川県 神奈川県横浜市港北区日吉本町四丁目 カナガワケンヨコハマシコウホククヒヨシホンチョウヨンチョウメ 045-123-4033 139.6316 35.54655 890.0
21 S13016 小金井店 13 東京都 東京都小金井市本町一丁目 トウキョウトコガネイシホンチョウイッチョウメ 042-123-4015 139.5094 35.70018 1399.0
22 S14034 川崎野川店 14 神奈川県 神奈川県川崎市宮前区野川 カナガワケンカワサキシミヤマエクノガワ 044-123-4044 139.5998 35.57693 1318.0
23 S13008 成城店 13 東京都 東京都世田谷区成城三丁目 トウキョウトセタガヤクセイジョウサンチョウメ 03-0123-4012 139.5966 35.63614 883.0
24 S13020 十条仲原店 13 東京都 東京都北区十条仲原三丁目 トウキョウトキタクジュウジョウナカハラサンチョウメ 03-0123-4019 139.7186 35.76686 801.0
25 S13043 南品川店 13 東京都 東京都品川区南品川三丁目 トウキョウトシナガワクミナミシナガワサンチョウメ 03-0123-4027 139.7436 35.60981 845.0
26 S14048 中川中央店 14 神奈川県 神奈川県横浜市都筑区中川中央二丁目 カナガワケンヨコハマシツヅキクナカガワチュウオウニチョウメ 045-123-4051 139.5758 35.54912 1657.0
27 S12007 佐倉店 12 千葉県 千葉県佐倉市上志津 チバケンサクラシカミシヅ 043-123-4001 140.1452 35.71872 1895.0
28 S14026 辻堂西海岸店 14 神奈川県 神奈川県藤沢市辻堂西海岸二丁目 カナガワケンフジサワシツジドウニシカイガンニチョウメ 046-123-4040 139.4466 35.32464 1732.0
29 S13041 八王子店 13 東京都 東京都八王子市大塚 トウキョウトハチオウジシオオツカ 042-123-4026 139.4235 35.63787 810.0
30 S13017 高円寺南店 13 東京都 東京都杉並区高円寺南四丁目 トウキョウトスギナミクコウエンジミナミヨンチョウメ 03-0123-4016 139.6513 35.70273 841.0
31 S14049 川崎大師店 14 神奈川県 神奈川県川崎市川崎区中瀬三丁目 カナガワケンカワサキシカワサキクナカゼサンチョウメ 044-123-4052 139.7327 35.53759 962.0
32 S14023 川崎店 14 神奈川県 神奈川県川崎市川崎区本町二丁目 カナガワケンカワサキシカワサキクホンチョウニチョウメ 044-123-4037 139.7028 35.53599 1804.0
33 S13018 清瀬店 13 東京都 東京都清瀬市松山一丁目 トウキョウトキヨセシマツヤマイッチョウメ 042-123-4017 139.5178 35.76885 1220.0
34 S13035 用賀四丁目店 13 東京都 東京都世田谷区用賀四丁目 トウキョウトセタガヤクヨウガヨンチョウメ 03-0123-4022 139.6318 35.63029 988.0
35 S14027 南藤沢店 14 神奈川県 神奈川県藤沢市南藤沢 カナガワケンフジサワシミナミフジサワ 046-123-4041 139.4896 35.33762 1521.0
36 S14021 伊勢原店 14 神奈川県 神奈川県伊勢原市伊勢原四丁目 カナガワケンイセハラシイセハラヨンチョウメ 046-123-4035 139.3129 35.40169 962.0
37 S14047 相模原店 14 神奈川県 神奈川県相模原市千代田六丁目 カナガワケンサガミハラシチヨダロクチョウメ 042-123-4050 139.3748 35.55959 1047.0
38 S12013 習志野店 12 千葉県 千葉県習志野市芝園一丁目 チバケンナラシノシシバゾノイッチョウメ 047-123-4002 140.0220 35.66122 808.0
39 S13032 仲六郷店 13 東京都 東京都大田区仲六郷三丁目 トウキョウトオオタクナカロクゴウサンチョウメ 03-0123-4021 139.7123 35.54682 1354.0
40 S14042 新山下店 14 神奈川県 神奈川県横浜市中区新山下二丁目 カナガワケンヨコハマシナカクシンヤマシタニチョウメ 045-123-4047 139.6593 35.43894 1044.0
41 S13039 南荻窪店 13 東京都 東京都杉並区南荻窪四丁目 トウキョウトスギナミクミナミオギクボヨンチョウメ 03-0123-4025 139.6152 35.70045 1133.0
42 S12030 八幡店 12 千葉県 千葉県市川市八幡三丁目 チバケンイチカワシヤワタサンチョウメ 047-123-4005 139.9240 35.72318 1162.0
43 S13009 用賀店 13 東京都 東京都世田谷区用賀二丁目 トウキョウトセタガヤクヨウガニチョウメ 03-0123-4013 139.6382 35.62720 1243.0
44 S14025 大和店 14 神奈川県 神奈川県大和市下和田 カナガワケンヤマトシシモワダ 046-123-4039 139.4680 35.43414 1011.0
45 S14045 厚木店 14 神奈川県 神奈川県厚木市中町二丁目 カナガワケンアツギシナカチョウニチョウメ 046-123-4048 139.3651 35.44182 980.0
46 S13005 白鷺店 13 東京都 東京都中野区白鷺三丁目 トウキョウトナカノクシラサギサンチョウメ 03-0123-4011 139.6307 35.72246 1259.0
47 S12029 東野店 12 千葉県 千葉県浦安市東野一丁目 チバケンウラヤスシヒガシノイッチョウメ 047-123-4004 139.8968 35.65086 1101.0
48 S13003 狛江店 13 東京都 東京都狛江市和泉本町四丁目 トウキョウトコマエシイズミホンチョウヨンチョウメ 03-0123-4009 139.5668 35.64462 1529.0
49 S12053 高洲店 12 千葉県 千葉県浦安市高洲五丁目 チバケンウラヤスシタカスゴチョウメ 047-123-4006 139.9176 35.63755 1555.0
50 S13037 南砂一丁目店 13 東京都 東京都江東区南砂一丁目 トウキョウトコウトウクミナミスナイッチョウメ 03-0123-4023 139.8215 35.67898 814.0
51 S14024 三田店 14 神奈川県 神奈川県川崎市多摩区三田四丁目 カナガワケンカワサキシタマクミタヨンチョウメ 044-123-4038 139.5424 35.60770 972.0
52 S14006 葛が谷店 14 神奈川県 神奈川県横浜市都筑区葛が谷 カナガワケンヨコハマシツヅキククズガヤ 045-123-4031 139.5633 35.53573 1886.0


続いて、df_productを確認します。


1
df_product


出力
1
2
3
4
5
6
7
8
9
10
11
12
13
  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_store52件、df_product10030件で有ることが分かります。全ての組み合わせのパタンなので、53 ×100030 = 531590が答えになることが予想されます。


これを導いていきましょう。


方法としては、2つのデータフレームにおいて全ての組み合わせでくっつけたデータフレームを新たに作成し、そのレコード数を数えていきたいと思います。


まず2つのデータフレームを結合する上で着目する共通カラムですが、今回に関しては共通カラムがありません。


2つのデータフレームを結合する上で、共通的なカラムデータを擬似的に作成し、擬似的に作成した共通カラムデータを指定して、merge()メソッドを用いて結合していきます。


結合方式は、全ての組み合わせパタンになるので、完全外部結合を適用します。完全外部結合とは、「両方のテーブルの全データを取り出して、くっつけられる範囲でくっつける」方式です。


まずは、各データフレームのコピーを作成し、共通的なカラムデータとしてkeyカラムを作成していきます。


1
2
df_store_tmp = df_store.copy()
df_product_tmp = df_product.copy()


keyカラムには、全て0を代入します。


1
2
df_store_tmp['key'] = 0
df_product_tmp['key'] = 0


作成した各データフレームを確認していきましょう。


1
df_store_tmp.head(5)


出力
1
2
3
4
5
6
7

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


1
df_product_tmp.head(5)


出力
1
2
3
4
5
6
  product_cd  category_major_cd category_medium_cd  category_small_cd unit_price  unit_cost key
0 P040101001 04 0401 040101 198.0 149.0 0
1 P040101002 04 0401 040101 218.0 164.0 0
2 P040101003 04 0401 040101 230.0 173.0 0
3 P040101004 04 0401 040101 248.0 186.0 0
4 P040101005 04 0401 040101 268.0 201.0 0


取得した2つのデータフレームを完全外部結合していきます。


1
2
df_result = pd.merge(df_store_tmp, df_product_tmp, how='outer', on='key')
df_result


出力
1
2
3
4
5
6
7
8
9
10
11
12
13
  store_cd  store_name  prefecture_cd prefecture  address address_kana  tel_no  longitude latitude  floor_area  key product_cd  category_major_cd category_medium_cd  category_small_cd unit_price  unit_cost
0 S12014 千草台店 12 千葉県 千葉県千葉市稲毛区千草台一丁目 チバケンチバシイナゲクチグサダイイッチョウメ 043-123-4003 140.1180 35.63559 1698.0 0 P040101001 04 0401 040101 198.0 149.0
1 S12014 千草台店 12 千葉県 千葉県千葉市稲毛区千草台一丁目 チバケンチバシイナゲクチグサダイイッチョウメ 043-123-4003 140.1180 35.63559 1698.0 0 P040101002 04 0401 040101 218.0 164.0
2 S12014 千草台店 12 千葉県 千葉県千葉市稲毛区千草台一丁目 チバケンチバシイナゲクチグサダイイッチョウメ 043-123-4003 140.1180 35.63559 1698.0 0 P040101003 04 0401 040101 230.0 173.0
3 S12014 千草台店 12 千葉県 千葉県千葉市稲毛区千草台一丁目 チバケンチバシイナゲクチグサダイイッチョウメ 043-123-4003 140.1180 35.63559 1698.0 0 P040101004 04 0401 040101 248.0 186.0
4 S12014 千草台店 12 千葉県 千葉県千葉市稲毛区千草台一丁目 チバケンチバシイナゲクチグサダイイッチョウメ 043-123-4003 140.1180 35.63559 1698.0 0 P040101005 04 0401 040101 268.0 201.0
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
531585 S14006 葛が谷店 14 神奈川県 神奈川県横浜市都筑区葛が谷 カナガワケンヨコハマシツヅキククズガヤ 045-123-4031 139.5633 35.53573 1886.0 0 P091503001 09 0915 091503 280.0 210.0
531586 S14006 葛が谷店 14 神奈川県 神奈川県横浜市都筑区葛が谷 カナガワケンヨコハマシツヅキククズガヤ 045-123-4031 139.5633 35.53573 1886.0 0 P091503002 09 0915 091503 680.0 510.0
531587 S14006 葛が谷店 14 神奈川県 神奈川県横浜市都筑区葛が谷 カナガワケンヨコハマシツヅキククズガヤ 045-123-4031 139.5633 35.53573 1886.0 0 P091503003 09 0915 091503 1080.0 810.0
531588 S14006 葛が谷店 14 神奈川県 神奈川県横浜市都筑区葛が谷 カナガワケンヨコハマシツヅキククズガヤ 045-123-4031 139.5633 35.53573 1886.0 0 P091503004 09 0915 091503 1130.0 848.0
531589 S14006 葛が谷店 14 神奈川県 神奈川県横浜市都筑区葛が谷 カナガワケンヨコハマシツヅキククズガヤ 045-123-4031 139.5633 35.53573 1886.0 0 P091503005 09 0915 091503 1280.0 960.0
531590 rows × 17 columns


これで完成です。




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

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


外部結合だけでなく、ソートや前方一致などの方法の復習になったと思います。


>> 続きはこちら

コメント