diff --git a/README.rst b/README.rst index 54306dfb..d12a5884 100644 --- a/README.rst +++ b/README.rst @@ -14,8 +14,8 @@ Overview - 言語によっては向かない設問もあるが、「この言語のときはこう書けば実現できる」という技術習得を目指すことを優先 - 個人情報のように見える項目は全てダミーデータを利用 - 大学、企業など組織でのご利用にあたっては、「データサイエンティスト協会スキル定義委員」の「データサイエンス100本ノック(構造化データ加工編)」を利用していることを明示いただければ自由に利用してOK -- データサイエンス100本ノック(構造化データ加工編)の解説本はこちら - - https://www.amazon.co.jp/dp/4802613563 +- データサイエンス100本ノック(構造化データ加工編)の解説本はこちら + - https://www.amazon.co.jp/dp/4802613563 - データサイエンス100本ノック(構造化データ加工編)の利用に関するご質問等について、個別での対応は受けかねますので予めご了承ください - データサイエンス100本ノック(構造化データ加工編)の利用により生じるいかなる問題についても、当協会は一切の責任を負いかねますのであらかじめご了承ください @@ -35,15 +35,16 @@ Requirement Install ==== + :: - git clone git@github.com:The-Japan-DataScientist-Society/100knocks-preprocess.git - cd 100knocks-preprocess - docker-compose up -d --build + + git clone git@github.com:The-Japan-DataScientist-Society/100knocks-preprocess.git + cd 100knocks-preprocess + docker-compose up -d --build ※ macOSでユーザーのホームディレクトリ配下以外にファイル群を配置する場合、Dockerの共有設定が別途必要となります -※ Windowsでgitを利用する場合、デフォルト設定でのインストールを行うとスクリプトの改行コードを変えられてしまい、データベースを正しく構築できないことがあります -- https://github.com/The-Japan-DataScientist-Society/100knocks-preprocess/issues/1#issue-640590032 +※ Windowsでgitを利用する場合、デフォルト設定でのインストールを行うとスクリプトの改行コードを変えられてしまい、データベースを正しく構築できないことがあります https://github.com/The-Japan-DataScientist-Society/100knocks-preprocess/issues/1#issue-640590032 ※ 改行を変えないよう設定するか、ZIPをダウンロードして利用してください @@ -56,9 +57,6 @@ Usage - ブラウザで以下のURLにアクセスします http://localhost:8888 -- Docker Toolboxの場合 -http://192.168.99.100:8888 - Document ==== - doc配下にデータサイエンス100本ノック(構造化データ加工編)の説明資料と設問PDF、設問HTML、解答例HTMLを配置 @@ -70,18 +68,23 @@ Link ==== 本コンテンツの内容やセットアップ手順について解説いただいているサイト、Dockerについて基本から学べるサイト -- 【データサイエンスを学ぶあなたへ】100本ノック - 構造化データ処理編 - 最速レビュー動画!【データサイエンティスト協会】#062 - - https://www.youtube.com/watch?v=fAyj0V2iAc4 -- データサイエンス100本ノック(構造化データ加工編)を試してみた - - https://qrunch.net/@hanar/entries/kSZfFS1MXK8H7U7x -- Macでデータサイエンス100本ノックを動かす方法 - - https://qiita.com/karaage0703/items/1b18b1f4ab65d35afb5f -- さくらのナレッジ - - https://knowledge.sakura.ad.jp/13265/ -- データサイエンス100本ノックを、Google ColabとAzure Notebooksで気軽に行いたい! - - https://qiita.com/noguhiro2002/items/de49db61b69c3dbc9282 -- データサイエンス初学者にむけた、データサイエンス100本ノックを実装する方法(windows10 Home向け) - - https://qiita.com/syuki-read/items/714fe66bf5c16b8a7407#comment-394d2f7656bd5b977e11 +- 【データサイエンスを学ぶあなたへ】100本ノック - 構造化データ処理編 - 最速レビュー動画!【データサイエンティスト協会】#062 + - https://www.youtube.com/watch?v=fAyj0V2iAc4 + +- データサイエンス100本ノック(構造化データ加工編)を試してみた + - https://qrunch.net/@hanar/entries/kSZfFS1MXK8H7U7x + +- Macでデータサイエンス100本ノックを動かす方法 + - https://qiita.com/karaage0703/items/1b18b1f4ab65d35afb5f + +- さくらのナレッジ + - https://knowledge.sakura.ad.jp/13265/ + +- データサイエンス100本ノックを、Google ColabとAzure Notebooksで気軽に行いたい! + - https://qiita.com/noguhiro2002/items/de49db61b69c3dbc9282 + +- データサイエンス初学者にむけた、データサイエンス100本ノックを実装する方法(windows10 Home向け) + - https://qiita.com/syuki-read/items/714fe66bf5c16b8a7407#comment-394d2f7656bd5b977e11 Author ==== diff --git a/docker/doc/100knocks_ER.pdf b/docker/doc/100knocks_ER.pdf index 414df3d4..39f8ac75 100644 Binary files a/docker/doc/100knocks_ER.pdf and b/docker/doc/100knocks_ER.pdf differ diff --git a/docker/doc/100knocks_guide.pdf b/docker/doc/100knocks_guide.pdf index 6ef94d41..e8719061 100644 Binary files a/docker/doc/100knocks_guide.pdf and b/docker/doc/100knocks_guide.pdf differ diff --git a/docker/doc/100knocks_questions.pdf b/docker/doc/100knocks_questions.pdf index cec13174..3588cca2 100644 Binary files a/docker/doc/100knocks_questions.pdf and b/docker/doc/100knocks_questions.pdf differ diff --git a/docker/doc/answer/ans_preprocess_knock_Python.html b/docker/doc/answer/ans_preprocess_knock_Python.html index 12b678f9..e63463d1 100644 --- a/docker/doc/answer/ans_preprocess_knock_Python.html +++ b/docker/doc/answer/ans_preprocess_knock_Python.html @@ -14545,9 +14545,12 @@
P-001: レシート明細のデータフレーム(df_receipt)から全項目の先頭10件を表示し、どのようなデータを保有しているか目視で確認せよ。
+P-001: レシート明細データ(df_receipt)から全項目の先頭10件を表示し、どのようなデータを保有しているか目視で確認せよ。
P-002: レシート明細のデータフレーム(df_receipt)から売上日(sales_ymd)、顧客ID(customer_id)、商品コード(product_cd)、売上金額(amount)の順に列を指定し、10件表示させよ。
+P-002: レシート明細データ(df_receipt)から売上年月日(sales_ymd)、顧客ID(customer_id)、商品コード(product_cd)、売上金額(amount)の順に列を指定し、10件表示せよ。
P-003: レシート明細のデータフレーム(df_receipt)から売上日(sales_ymd)、顧客ID(customer_id)、商品コード(product_cd)、売上金額(amount)の順に列を指定し、10件表示させよ。ただし、sales_ymdはsales_dateに項目名を変更しながら抽出すること。
+P-003: レシート明細データ(df_receipt)から売上年月日(sales_ymd)、顧客ID(customer_id)、商品コード(product_cd)、売上金額(amount)の順に列を指定し、10件表示せよ。ただし、sales_ymdsales_dateに項目名を変更しながら抽出すること。
P-004: レシート明細のデータフレーム(df_receipt)から売上日(sales_ymd)、顧客ID(customer_id)、商品コード(product_cd)、売上金額(amount)の順に列を指定し、以下の条件を満たすデータを抽出せよ。
+P-004: レシート明細データ(df_receipt)から売上日(sales_ymd)、顧客ID(customer_id)、商品コード(product_cd)、売上金額(amount)の順に列を指定し、以下の条件を満たすデータを抽出せよ。
@@ -15073,7 +15076,8 @@
- 顧客ID(customer_id)が"CS018205000001"
演習問題In [5]:
df_receipt[['sales_ymd', 'customer_id', 'product_cd', 'amount']]. \
+# コード例1(queryを使う場合)
+df_receipt[['sales_ymd', 'customer_id', 'product_cd', 'amount']]. \
query('customer_id == "CS018205000001"')
@@ -15215,11 +15219,160 @@ 演習問題
+
# コード例1(queryを使わない場合)
+df = df_receipt[['sales_ymd', 'customer_id', 'product_cd', 'amount']]
+df[df['customer_id'] == 'CS018205000001']
+
+ | sales_ymd | +customer_id | +product_cd | +amount | +
---|---|---|---|---|
36 | +20180911 | +CS018205000001 | +P071401012 | +2200 | +
9843 | +20180414 | +CS018205000001 | +P060104007 | +600 | +
21110 | +20170614 | +CS018205000001 | +P050206001 | +990 | +
27673 | +20170614 | +CS018205000001 | +P060702015 | +108 | +
27840 | +20190216 | +CS018205000001 | +P071005024 | +102 | +
28757 | +20180414 | +CS018205000001 | +P071101002 | +278 | +
39256 | +20190226 | +CS018205000001 | +P070902035 | +168 | +
58121 | +20190924 | +CS018205000001 | +P060805001 | +495 | +
68117 | +20190226 | +CS018205000001 | +P071401020 | +2200 | +
72254 | +20180911 | +CS018205000001 | +P071401005 | +1100 | +
88508 | +20190216 | +CS018205000001 | +P040101002 | +218 | +
91525 | +20190924 | +CS018205000001 | +P091503001 | +280 | +
P-005: レシート明細のデータフレーム(df_receipt)から売上日(sales_ymd)、顧客ID(customer_id)、商品コード(product_cd)、売上金額(amount)の順に列を指定し、以下の条件を満たすデータを抽出せよ。
+P-005: レシート明細データ(df_receipt)から売上日(sales_ymd)、顧客ID(customer_id)、商品コード(product_cd)、売上金額(amount)の順に列を指定し、以下の全ての条件を満たすデータを抽出せよ。
- 顧客ID(customer_id)が"CS018205000001"
- 売上金額(amount)が1,000以上
@@ -15230,7 +15383,7 @@演習問題
-In [6]:+In [7]:df_receipt[['sales_ymd', 'customer_id', 'product_cd', 'amount']] \ @@ -15250,7 +15403,7 @@演習問題 -
Out[6]:+Out[7]:@@ -15316,7 +15469,7 @@演習問題
-P-006: レシート明細データフレーム「df_receipt」から売上日(sales_ymd)、顧客ID(customer_id)、商品コード(product_cd)、売上数量(quantity)、売上金額(amount)の順に列を指定し、以下の条件を満たすデータを抽出せよ。
+P-006: レシート明細データ(df_receipt)から売上日(sales_ymd)、顧客ID(customer_id)、商品コード(product_cd)、売上数量(quantity)、売上金額(amount)の順に列を指定し、以下の全ての条件を満たすデータを抽出せよ。
- 顧客ID(customer_id)が"CS018205000001"
- 売上金額(amount)が1,000以上または売上数量(quantity)が5以上
@@ -15327,7 +15480,7 @@演習問題
-In [7]:+In [8]:df_receipt[['sales_ymd', 'customer_id', 'product_cd', 'quantity', 'amount']].\ @@ -15347,7 +15500,7 @@演習問題 -
Out[7]:+Out[8]:@@ -15433,7 +15586,7 @@演習問題
-P-007: レシート明細のデータフレーム(df_receipt)から売上日(sales_ymd)、顧客ID(customer_id)、商品コード(product_cd)、売上金額(amount)の順に列を指定し、以下の条件を満たすデータを抽出せよ。
+P-007: レシート明細データ(df_receipt)から売上日(sales_ymd)、顧客ID(customer_id)、商品コード(product_cd)、売上金額(amount)の順に列を指定し、以下の全ての条件を満たすデータを抽出せよ。
- 顧客ID(customer_id)が"CS018205000001"
- 売上金額(amount)が1,000以上2,000以下
@@ -15444,7 +15597,7 @@演習問題
-In [8]:+In [9]:df_receipt[['sales_ymd', 'customer_id', 'product_cd', 'amount']] \ @@ -15464,7 +15617,7 @@演習問題 -
Out[8]:+Out[9]:@@ -15516,7 +15669,7 @@演習問題
-P-008: レシート明細のデータフレーム(df_receipt)から売上日(sales_ymd)、顧客ID(customer_id)、商品コード(product_cd)、売上金額(amount)の順に列を指定し、以下の条件を満たすデータを抽出せよ。
+P-008: レシート明細データ(df_receipt)から売上日(sales_ymd)、顧客ID(customer_id)、商品コード(product_cd)、売上金額(amount)の順に列を指定し、以下の全ての条件を満たすデータを抽出せよ。
- 顧客ID(customer_id)が"CS018205000001"
- 商品コード(product_cd)が"P071401019"以外
@@ -15527,7 +15680,7 @@演習問題
-In [9]:+In [10]:df_receipt[['sales_ymd', 'customer_id', 'product_cd', 'amount']] \ @@ -15547,7 +15700,7 @@演習問題 -
Out[9]:+Out[10]:@@ -15677,14 +15830,14 @@演習問題
P-009: 以下の処理において、出力結果を変えずにORをANDに書き換えよ。
-+
df_store.query('not(prefecture_cd == "13" | floor_area > 900)')
-In [10]:+In [11]:df_store.query('prefecture_cd != "13" & floor_area <= 900') @@ -15703,7 +15856,7 @@演習問題 -
Out[10]:+Out[11]:@@ -15793,14 +15946,14 @@演習問題
-P-010: 店舗データフレーム(df_store)から、店舗コード(store_cd)が"S14"で始まるものだけ全項目抽出し、10件だけ表示せよ。
+P-010: 店舗データ(df_store)から、店舗コード(store_cd)が"S14"で始まるものだけ全項目抽出し、10件表示せよ。
-In [11]:+In [12]:df_store.query("store_cd.str.startswith('S14')", engine='python').head(10) @@ -15819,7 +15972,7 @@演習問題 -
Out[11]:+Out[12]:@@ -16000,14 +16153,14 @@演習問題
-P-011: 顧客データフレーム(df_customer)から顧客ID(customer_id)の末尾が1のものだけ全項目抽出し、10件だけ表示せよ。
+P-011: 顧客データ(df_customer)から顧客ID(customer_id)の末尾が1のものだけ全項目抽出し、10件表示せよ。
-In [12]:+In [13]:df_customer.query("customer_id.str.endswith('1')", engine='python').head(10) @@ -16026,7 +16179,7 @@演習問題 -
Out[12]:+Out[13]:@@ -16218,14 +16371,14 @@演習問題
-P-012: 店舗データフレーム(df_store)から横浜市の店舗だけ全項目表示せよ。
+P-012: 店舗データ(df_store)から、住所 (address) に"横浜市"が含まれるものだけ全項目表示せよ。
-In [13]:+In [14]:df_store.query("address.str.contains('横浜市')", engine='python') @@ -16244,7 +16397,7 @@演習問題 -
Out[13]:+Out[14]:@@ -16438,17 +16591,17 @@演習問題
-P-013: 顧客データフレーム(df_customer)から、ステータスコード(status_cd)の先頭がアルファベットのA〜Fで始まるデータを全項目抽出し、10件だけ表示せよ。
+P-013: 顧客データ(df_customer)から、ステータスコード(status_cd)の先頭がアルファベットのA〜Fで始まるデータを全項目抽出し、10件表示せよ。
-In [14]:+In [15]:-df_customer.query("status_cd.str.contains('^[A-F]', regex=True)", +@@ -16465,7 +16618,7 @@df_customer.query("status_cd.str.contains(r'^[A-F]')", engine='python').head(10)演習問題 -
Out[14]:+Out[15]:@@ -16657,17 +16810,19 @@演習問題
-P-014: 顧客データフレーム(df_customer)から、ステータスコード(status_cd)の末尾が数字の1〜9で終わるデータを全項目抽出し、10件だけ表示せよ。
+P-014: 顧客データ(df_customer)から、ステータスコード(status_cd)の末尾が数字の1〜9で終わるデータを全項目抽出し、10件表示せよ。
-In [15]:+In [16]:-@@ -16683,7 +16838,7 @@df_customer.query("status_cd.str.contains('[1-9]$', regex=True)", engine='python').head(10) +# regexのオプションをつけることもできる(Falseにすれば正規表現ではなくそのままの文字列として扱われる) +df_customer.query("status_cd.str.contains(r'[1-9]$', regex=True)", + engine='python').head(10)演習問題 -
Out[15]:+Out[16]:@@ -16875,17 +17030,17 @@演習問題
-P-015: 顧客データフレーム(df_customer)から、ステータスコード(status_cd)の先頭がアルファベットのA〜Fで始まり、末尾が数字の1〜9で終わるデータを全項目抽出し、10件だけ表示せよ。
+P-015: 顧客データ(df_customer)から、ステータスコード(status_cd)の先頭がアルファベットのA〜Fで始まり、末尾が数字の1〜9で終わるデータを全項目抽出し、10件表示せよ。
-In [16]:+In [17]:-df_customer.query("status_cd.str.contains('^[A-F].*[1-9]$', regex=True)", +@@ -16902,7 +17057,7 @@df_customer.query("status_cd.str.contains(r'^[A-F].*[1-9]$')", engine='python').head(10)演習問題 -
Out[16]:+Out[17]:@@ -17094,17 +17249,17 @@演習問題
-P-016: 店舗データフレーム(df_store)から、電話番号(tel_no)が3桁-3桁-4桁のデータを全項目表示せよ。
+P-016: 店舗データ(df_store)から、電話番号(tel_no)が3桁-3桁-4桁のデータを全項目表示せよ。
-In [17]:+In [18]:-df_store.query("tel_no.str.contains('^[0-9]{3}-[0-9]{3}-[0-9]{4}$',regex=True)", +@@ -17121,7 +17276,7 @@df_store.query("tel_no.str.contains(r'^[0-9]{3}-[0-9]{3}-[0-9]{4}$')", engine='python')演習問題 -
Out[17]:+Out[18]:@@ -17614,17 +17769,17 @@演習問題
-P-017: 顧客データフレーム(df_customer)を生年月日(birth_day)で高齢順にソートし、先頭10件を全項目表示せよ。
+P-017: 顧客データ(df_customer)を生年月日(birth_day)で高齢順にソートし、先頭から全項目を10件表示せよ。
-In [18]:+In [19]:-@@ -17640,7 +17795,7 @@df_customer.sort_values('birth_day', ascending=True).head(10) +df_customer.sort_values('birth_day').head(10)演習問題 -
Out[18]:+Out[19]:@@ -17832,14 +17987,14 @@演習問題
-P-018: 顧客データフレーム(df_customer)を生年月日(birth_day)で若い順にソートし、先頭10件を全項目表示せよ。
+P-018: 顧客データ(df_customer)を生年月日(birth_day)で若い順にソートし、先頭から全項目を10件表示せよ。
-In [19]:+In [20]:df_customer.sort_values('birth_day', ascending=False).head(10) @@ -17858,7 +18013,7 @@演習問題 -
Out[19]:+Out[20]:@@ -18050,21 +18205,23 @@演習問題
-P-019: レシート明細データフレーム(df_receipt)に対し、1件あたりの売上金額(amount)が高い順にランクを付与し、先頭10件を抽出せよ。項目は顧客ID(customer_id)、売上金額(amount)、付与したランクを表示させること。なお、売上金額(amount)が等しい場合は同一順位を付与するものとする。
+P-019: レシート明細データ(df_receipt)に対し、1件あたりの売上金額(amount)が高い順にランクを付与し、先頭から10件表示せよ。項目は顧客ID(customer_id)、売上金額(amount)、付与したランクを表示させること。なお、売上金額(amount)が等しい場合は同一順位を付与するものとする。
-In [20]:+In [21]:@@ -18080,7 +18237,7 @@df_tmp = pd.concat([df_receipt[['customer_id', 'amount']] ,df_receipt['amount'].rank(method='min', ascending=False)], axis=1) + df_tmp.columns = ['customer_id', 'amount', 'ranking'] -df_tmp.sort_values('ranking', ascending=True).head(10) + +df_tmp.sort_values('ranking').head(10)演習問題 -
Out[20]:+Out[21]:@@ -18184,21 +18341,23 @@演習問題
-P-020: レシート明細データフレーム(df_receipt)に対し、1件あたりの売上金額(amount)が高い順にランクを付与し、先頭10件を抽出せよ。項目は顧客ID(customer_id)、売上金額(amount)、付与したランクを表示させること。なお、売上金額(amount)が等しい場合でも別順位を付与すること。
+P-020: レシート明細データ(df_receipt)に対し、1件あたりの売上金額(amount)が高い順にランクを付与し、先頭から10件表示せよ。項目は顧客ID(customer_id)、売上金額(amount)、付与したランクを表示させること。なお、売上金額(amount)が等しい場合でも別順位を付与すること。
-In [21]:+In [22]:@@ -18214,7 +18373,7 @@df_tmp = pd.concat([df_receipt[['customer_id', 'amount']] ,df_receipt['amount'].rank(method='first', ascending=False)], axis=1) + df_tmp.columns = ['customer_id', 'amount', 'ranking'] -df_tmp.sort_values('ranking', ascending=True).head(10) + +df_tmp.sort_values('ranking').head(10)演習問題 -
Out[21]:+Out[22]:@@ -18318,14 +18477,14 @@演習問題
-P-021: レシート明細データフレーム(df_receipt)に対し、件数をカウントせよ。
+P-021: レシート明細データ(df_receipt)に対し、件数をカウントせよ。
-In [22]:+In [23]:len(df_receipt) @@ -18344,7 +18503,7 @@演習問題 -
Out[22]:+Out[23]:@@ -18363,14 +18522,14 @@演習問題
-P-022: レシート明細データフレーム(df_receipt)の顧客ID(customer_id)に対し、ユニーク件数をカウントせよ。
+P-022: レシート明細データ(df_receipt)の顧客ID(customer_id)に対し、ユニーク件数をカウントせよ。
-In [23]:+In [24]:len(df_receipt['customer_id'].unique()) @@ -18389,7 +18548,7 @@演習問題 -
Out[23]:+Out[24]:@@ -18408,17 +18567,18 @@演習問題
-P-023: レシート明細データフレーム(df_receipt)に対し、店舗コード(store_cd)ごとに売上金額(amount)と売上数量(quantity)を合計せよ。
+P-023: レシート明細データ(df_receipt)に対し、店舗コード(store_cd)ごとに売上金額(amount)と売上数量(quantity)を合計せよ。
-In [24]:+In [25]:-+-df_receipt.groupby('store_cd').agg({'amount':'sum', +@@ -18435,7 +18595,7 @@# コード例1 +df_receipt.groupby('store_cd').agg({'amount':'sum', 'quantity':'sum'}).reset_index()演習問題 -
Out[24]:+Out[25]:@@ -18787,21 +18947,14 @@演習問題 -
--
-- -P-024: レシート明細データフレーム(df_receipt)に対し、顧客ID(customer_id)ごとに最も新しい売上日(sales_ymd)を求め、10件表示せよ。
-+ ++ +-+ +In [25]:+In [26]:+ +-+@@ -18817,7 +18970,7 @@df_receipt.groupby('customer_id').sales_ymd.max().reset_index().head(10) +# コード例2 +df_receipt.groupby('store_cd')[['amount','quantity']].agg('sum').reset_index()演習問題 -
Out[25]:+Out[26]:@@ -18840,60 +18993,1657 @@演習問題
- customer_id -sales_ymd +store_cd +amount +quantity 0 -CS001113000004 -20190308 +S12007 +638761 +2099 + 1 -CS001114000005 -20190731 +S12013 +787513 +2425 ++ +2 +S12014 +725167 +2358 ++ +3 +S12029 +794741 +2555 ++ +4 +S12030 +684402 +2403 ++ +5 +S13001 +811936 +2347 ++ +6 +S13002 +727821 +2340 ++ +7 +S13003 +764294 +2197 ++ +8 +S13004 +779373 +2390 ++ +9 +S13005 +629876 +2004 ++ +10 +S13008 +809288 +2491 ++ +11 +S13009 +808870 +2486 ++ +12 +S13015 +780873 +2248 ++ +13 +S13016 +793773 +2432 ++ +14 +S13017 +748221 +2376 ++ +15 +S13018 +790535 +2562 ++ +16 +S13019 +827833 +2541 ++ +17 +S13020 +796383 +2383 ++ +18 +S13031 +705968 +2336 ++ +19 +S13032 +790501 +2491 ++ +20 +S13035 +715869 +2219 ++ +21 +S13037 +693087 +2344 ++ +22 +S13038 +708884 +2337 ++ +23 +S13039 +611888 +1981 ++ +24 +S13041 +728266 +2233 ++ +25 +S13043 +587895 +1881 ++ +26 +S13044 +520764 +1729 ++ +27 +S13051 +107452 +354 ++ +28 +S13052 +100314 +250 ++ +29 +S14006 +712839 +2284 ++ +30 +S14010 +790361 +2290 ++ +31 +S14011 +805724 +2434 ++ +32 +S14012 +720600 +2412 ++ +33 +S14021 +699511 +2231 ++ +34 +S14022 +651328 +2047 ++ +35 +S14023 +727630 +2258 ++ +36 +S14024 +736323 +2417 ++ +37 +S14025 +755581 +2394 ++ +38 +S14026 +824537 +2503 ++ +39 +S14027 +714550 +2303 ++ +40 +S14028 +786145 +2458 ++ +41 +S14033 +725318 +2282 ++ +42 +S14034 +653681 +2024 ++ +43 +S14036 +203694 +635 ++ +44 +S14040 +701858 +2233 ++ +45 +S14042 +534689 +1935 ++ +46 +S14045 +458484 +1398 ++ +47 +S14046 +412646 +1354 ++ +48 +S14047 +338329 +1041 ++ +49 +S14048 +234276 +769 ++ +50 +S14049 +230808 +788 ++ + + +51 +S14050 +167090 +580 ++++
++ +P-024: レシート明細データ(df_receipt)に対し、顧客ID(customer_id)ごとに最も新しい売上年月日(sales_ymd)を求め、10件表示せよ。
+++++ +++In [27]:++++++ +df_receipt.groupby('customer_id').agg({'sales_ymd': 'max'}).reset_index().head(10) ++ + ++ ++ ++ ++ + ++ +Out[27]:+ + + +++ ++ +++ +
++ + + ++ customer_id +sales_ymd ++ +0 +CS001113000004 +20190308 ++ +1 +CS001114000005 +20190731 ++ +2 +CS001115000010 +20190405 ++ +3 +CS001205000004 +20190625 ++ +4 +CS001205000006 +20190224 ++ +5 +CS001211000025 +20190322 ++ +6 +CS001212000027 +20170127 ++ +7 +CS001212000031 +20180906 ++ +8 +CS001212000046 +20170811 ++ + +9 +CS001212000070 +20191018 ++++
++ +P-025: レシート明細データ(df_receipt)に対し、顧客ID(customer_id)ごとに最も古い売上年月日(sales_ymd)を求め、10件表示せよ。
+++++ +++In [28]:++++++ +# 024と同じ書き方もできるがあえて違う書き方で解答例を紹介 +df_receipt.groupby('customer_id').sales_ymd.min().reset_index().head(10) ++ + ++ ++ ++ ++ + ++ +Out[28]:+ + + +++ ++ +++ +
++ + + ++ customer_id +sales_ymd ++ +0 +CS001113000004 +20190308 ++ +1 +CS001114000005 +20180503 ++ +2 +CS001115000010 +20171228 ++ +3 +CS001205000004 +20170914 ++ +4 +CS001205000006 +20180207 ++ +5 +CS001211000025 +20190322 ++ +6 +CS001212000027 +20170127 ++ +7 +CS001212000031 +20180906 ++ +8 +CS001212000046 +20170811 ++ + +9 +CS001212000070 +20191018 ++++
++ +P-026: レシート明細データ(df_receipt)に対し、顧客ID(customer_id)ごとに最も新しい売上年月日(sales_ymd)と古い売上年月日を求め、両者が異なるデータを10件表示せよ。
+++++ +++In [29]:++++++ +df_tmp = df_receipt.groupby('customer_id'). \ + agg({'sales_ymd':['max','min']}).reset_index() + +# マルチインデックス(項目)の階層を"_"でつなぎながら1階層のインデックス(項目)にする +# df_tmp.columns = ['customer_id', 'sales_ymd_max', 'sales_ymd_min'] としても良い +df_tmp.columns = ["_".join(pair) for pair in df_tmp.columns] + +df_tmp.query('sales_ymd_max != sales_ymd_min').head(10) ++ + ++ ++ ++ ++ + ++ +Out[29]:+ + + +++ ++ +++ +
++ + + ++ customer_id_ +sales_ymd_max +sales_ymd_min ++ +1 +CS001114000005 +20190731 +20180503 ++ +2 +CS001115000010 +20190405 +20171228 ++ +3 +CS001205000004 +20190625 +20170914 ++ +4 +CS001205000006 +20190224 +20180207 ++ +13 +CS001214000009 +20190902 +20170306 ++ +14 +CS001214000017 +20191006 +20180828 ++ +16 +CS001214000048 +20190929 +20171109 ++ +17 +CS001214000052 +20190617 +20180208 ++ +20 +CS001215000005 +20181021 +20170206 ++ + +21 +CS001215000040 +20171022 +20170214 ++++
++ +P-027: レシート明細データ(df_receipt)に対し、店舗コード(store_cd)ごとに売上金額(amount)の平均を計算し、降順でTOP5を表示せよ。
+++++ +++In [30]:++++++ +df_receipt.groupby('store_cd').agg({'amount':'mean'}).reset_index(). \ + sort_values('amount', ascending=False).head(5) ++ + ++ ++ ++ ++ + ++ +Out[30]:+ + + +++ ++ +++ +
++ + + ++ store_cd +amount ++ +28 +S13052 +402.867470 ++ +12 +S13015 +351.111960 ++ +7 +S13003 +350.915519 ++ +30 +S14010 +348.791262 ++ + +5 +S13001 +348.470386 ++++
++ +P-028: レシート明細データ(df_receipt)に対し、店舗コード(store_cd)ごとに売上金額(amount)の中央値を計算し、降順でTOP5を表示せよ。
+++++ +++In [31]:++++++ +df_receipt.groupby('store_cd').agg({'amount':'median'}).reset_index(). \ + sort_values('amount', ascending=False).head(5) ++ + ++ ++ ++ ++ + ++ +Out[31]:+ + + +++ ++ +++ +
++ + + ++ store_cd +amount ++ +28 +S13052 +190.0 ++ +30 +S14010 +188.0 ++ +51 +S14050 +185.0 ++ +44 +S14040 +180.0 ++ + +7 +S13003 +180.0 ++++
++ +P-029: レシート明細データ(df_receipt)に対し、店舗コード(store_cd)ごとに商品コード(product_cd)の最頻値を求め、10件表示させよ。
+++++ +++In [32]:++++++ +df_receipt.groupby('store_cd').product_cd. \ + apply(lambda x: x.mode()).reset_index().head(10) ++ + ++ ++ ++ ++ + ++ +Out[32]:+ + + +++ ++ +++ +
++ + + ++ store_cd +level_1 +product_cd ++ +0 +S12007 +0 +P060303001 ++ +1 +S12013 +0 +P060303001 ++ +2 +S12014 +0 +P060303001 ++ +3 +S12029 +0 +P060303001 ++ +4 +S12030 +0 +P060303001 ++ +5 +S13001 +0 +P060303001 ++ +6 +S13002 +0 +P060303001 ++ +7 +S13003 +0 +P071401001 ++ +8 +S13004 +0 +P060303001 ++ + +9 +S13005 +0 +P040503001 ++++
++ +P-030: レシート明細データ(df_receipt)に対し、店舗コード(store_cd)ごとに売上金額(amount)の分散を計算し、降順で5件表示せよ。
+++++ +++In [33]:++++++ +df_receipt.groupby('store_cd').amount.var(ddof=0).reset_index(). \ + sort_values('amount', ascending=False).head(5) ++ + ++ ++ ++ ++ + ++ +Out[33]:+ + + +++ ++ +++ +
++ + + ++ store_cd +amount ++ +28 +S13052 +440088.701311 ++ +31 +S14011 +306314.558164 ++ +42 +S14034 +296920.081011 ++ +5 +S13001 +295431.993329 ++ + +12 +S13015 +295294.361116 +++++
++ +P-031: レシート明細データ(df_receipt)に対し、店舗コード(store_cd)ごとに売上金額(amount)の標準偏差を計算し、降順で5件表示せよ。
++++TIPS:
+PandasとNumpyでddofのデフォルト値が異なることに注意しましょう
+ ++ +Pandas: +DataFrame.std(self, axis=None, skipna=None, level=None, ddof=1, numeric_only=None, **kwargs) +Numpy: +numpy.std(a, axis=None, dtype=None, out=None, ddof=0, keepdims=)
++++ +++In [34]:++++++ +df_receipt.groupby('store_cd').amount.std(ddof=0).reset_index(). \ + sort_values('amount', ascending=False).head(5) ++ + ++ ++ ++ ++ + ++ +Out[34]:+ + + +++ ++ +++ +
++ + + ++ store_cd +amount ++ +28 +S13052 +663.391816 ++ +31 +S14011 +553.456916 ++ +42 +S14034 +544.903736 ++ +5 +S13001 +543.536561 ++ + +12 +S13015 +543.409938 ++++
++ +P-032: レシート明細データ(df_receipt)の売上金額(amount)について、25%刻みでパーセンタイル値を求めよ。
++++ +++In [35]:++++++ +# コード例1 +np.percentile(df_receipt['amount'], q=np.arange(1, 5) * 25) ++ + ++ ++ ++ ++ + ++ +Out[35]:+ + + + +++ +array([ 102., 170., 288., 10925.])+++++ +++In [36]:++++++ +# コード例2 +df_receipt.amount.quantile(q=np.arange(1, 5) / 4) ++ + ++ ++ ++ ++ + ++ +Out[36]:+ + + + +++ +0.25 102.0 +0.50 170.0 +0.75 288.0 +1.00 10925.0 +Name: amount, dtype: float64++++
++ +P-033: レシート明細データ(df_receipt)に対し、店舗コード(store_cd)ごとに売上金額(amount)の平均を計算し、330以上のものを抽出せよ。
+++++ +++In [37]:++++++ +df_receipt.groupby('store_cd').amount.mean(). \ + reset_index().query('amount >= 330') ++ + ++ ++ ++ ++ + ++ +Out[37]:+ + + +++ ++ +++ +
++ + + ++ store_cd +amount ++ +1 +S12013 +330.194130 ++ +5 +S13001 +348.470386 ++ +7 +S13003 +350.915519 ++ +8 +S13004 +330.943949 ++ +12 +S13015 +351.111960 ++ +16 +S13019 +330.208616 ++ +17 +S13020 +337.879932 ++ +28 +S13052 +402.867470 ++ +30 +S14010 +348.791262 ++ +31 +S14011 +335.718333 ++ +38 +S14026 +332.340588 ++ +46 +S14045 +330.082073 ++ + +48 +S14047 +330.077073 ++++
++ +P-034: レシート明細データ(df_receipt)に対し、顧客ID(customer_id)ごとに売上金額(amount)を合計して全顧客の平均を求めよ。ただし、顧客IDが"Z"から始まるものは非会員を表すため、除外して計算すること。
++++ +++In [38]:++++++ +# コード例1: queryを使わない書き方 +df_receipt[~df_receipt['customer_id'].str.startswith("Z")]. \ + groupby('customer_id').amount.sum().mean() ++ + ++ ++ ++ ++ + ++ +Out[38]:+ + + + +++ +2547.742234529256+++++ +++In [39]:++++++ +# コード例2: queryを使う書き方 +df_receipt.query('not customer_id.str.startswith("Z")', + engine='python').groupby('customer_id').amount.sum().mean() ++ + ++ ++ ++ ++ + ++ +Out[39]:+ + + + +++ +2547.742234529256++++
++ +P-035: レシート明細データ(df_receipt)に対し、顧客ID(customer_id)ごとに売上金額(amount)を合計して全顧客の平均を求め、平均以上に買い物をしている顧客を抽出し、10件表示せよ。ただし、顧客IDが"Z"から始まるものは非会員を表すため、除外して計算すること。
++++ +++In [40]:++++++ +df_amount_sum = df_receipt[~df_receipt['customer_id'].str.startswith("Z")].\ + groupby('customer_id').amount.sum() + +amount_mean = df_amount_sum.mean() + +df_amount_sum = df_amount_sum.reset_index() + +df_amount_sum[df_amount_sum['amount'] >= amount_mean].head(10) ++ + ++ ++ + +Out[40]:+ + + +++ ++ +
@@ -18910,17 +20660,18 @@+ + ++ customer_id +amount - 2 CS001115000010 -20190405 -- 3 -CS001205000004 -20190625 +3044 4 CS001205000006 -20190224 +3337 - 5 -CS001211000025 -20190322 +13 +CS001214000009 +4685 - 6 -CS001212000027 -20170127 +14 +CS001214000017 +4132 - 7 -CS001212000031 -20180906 +17 +CS001214000052 +5639 - 8 -CS001212000046 -20170811 +21 +CS001215000040 +3496 - +9 -CS001212000070 -20191018 +30 +CS001304000006 +3726 ++ +32 +CS001305000005 +3485 ++ +33 +CS001305000011 +4370 ++ 53 +CS001315000180 +3300 演習問題
-P-025: レシート明細データフレーム(df_receipt)に対し、顧客ID(customer_id)ごとに最も古い売上日(sales_ymd)を求め、10件表示せよ。
+P-036: レシート明細データ(df_receipt)と店舗データ(df_store)を内部結合し、レシート明細データの全項目と店舗データの店舗名(store_name)を10件表示せよ。
-In [26]:+In [41]:-@@ -18936,7 +20687,7 @@df_receipt.groupby('customer_id').agg({'sales_ymd':'min'}).head(10) +pd.merge(df_receipt, df_store[['store_cd','store_name']], + how='inner', on='store_cd').head(10)演習問題 -
Out[26]:+Out[41]:@@ -18960,52 +20711,147 @@演習問題
sales_ymd - -+ sales_epoch +store_cd +receipt_no +receipt_sub_no customer_id -+ product_cd +quantity +amount +store_name - CS001113000004 -20190308 +0 +20181103 +1541203200 +S14006 +112 +1 +CS006214000001 +P070305012 +1 +158 +葛が谷店 - CS001114000005 -20180503 +1 +20181116 +1542326400 +S14006 +112 +2 +ZZ000000000000 +P080401001 +1 +48 +葛が谷店 - CS001115000010 -20171228 +2 +20170118 +1484697600 +S14006 +1162 +1 +CS006815000006 +P050406035 +1 +220 +葛が谷店 - CS001205000004 -20170914 +3 +20190524 +1558656000 +S14006 +1192 +1 +CS006514000034 +P060104003 +1 +80 +葛が谷店 - CS001205000006 -20180207 +4 +20190419 +1555632000 +S14006 +112 +2 +ZZ000000000000 +P060501002 +1 +148 +葛が谷店 - CS001211000025 -20190322 +5 +20181119 +1542585600 +S14006 +1152 +2 +ZZ000000000000 +P050701001 +1 +88 +葛が谷店 - CS001212000027 -20170127 +6 +20171211 +1512950400 +S14006 +1132 +2 +CS006515000175 +P090903001 +1 +80 +葛が谷店 - CS001212000031 -20180906 +7 +20191021 +1571616000 +S14006 +1112 +2 +CS006415000221 +P040602001 +1 +405 +葛が谷店 - CS001212000046 -20170811 +8 +20170710 +1499644800 +S14006 +1132 +2 +CS006411000036 +P090301051 +1 +330 +葛が谷店 - @@ -19022,20 +20868,19 @@CS001212000070 -20191018 +9 +20190805 +1564963200 +S14006 +112 +1 +CS006211000012 +P050104001 +1 +115 +葛が谷店 演習問題
-P-026: レシート明細データフレーム(df_receipt)に対し、顧客ID(customer_id)ごとに最も新しい売上日(sales_ymd)と古い売上日を求め、両者が異なるデータを10件表示せよ。
+P-037: 商品データ(df_product)とカテゴリデータ(df_category)を内部結合し、商品データの全項目とカテゴリデータのカテゴリ小区分名(category_small_name)を10件表示せよ。
-In [27]:+In [42]:--@@ -19051,7 +20896,7 @@df_tmp = df_receipt.groupby('customer_id'). \ - agg({'sales_ymd':['max','min']}).reset_index() -df_tmp.columns = ["_".join(pair) for pair in df_tmp.columns] -df_tmp.query('sales_ymd_max != sales_ymd_min').head(10) +pd.merge(df_product + , df_category[['category_small_cd','category_small_name']] + , how='inner', on='category_small_cd').head(10)演習問題 -
Out[27]:+Out[42]:@@ -19074,71 +20919,115 @@演習問題
+ - customer_id_ -sales_ymd_max -sales_ymd_min +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 -CS001114000005 -20190731 -20180503 +P040101002 +04 +0401 +040101 +218.0 +164.0 +弁当類 2 -CS001115000010 -20190405 -20171228 +P040101003 +04 +0401 +040101 +230.0 +173.0 +弁当類 3 -CS001205000004 -20190625 -20170914 +P040101004 +04 +0401 +040101 +248.0 +186.0 +弁当類 - 4 -CS001205000006 -20190224 -20180207 -- 13 -CS001214000009 -20190902 -20170306 +P040101005 +04 +0401 +040101 +268.0 +201.0 +弁当類 - 14 -CS001214000017 -20191006 -20180828 +5 +P040101006 +04 +0401 +040101 +298.0 +224.0 +弁当類 - 16 -CS001214000048 -20190929 -20171109 +6 +P040101007 +04 +0401 +040101 +338.0 +254.0 +弁当類 - 17 -CS001214000052 -20190617 -20180208 +7 +P040101008 +04 +0401 +040101 +420.0 +315.0 +弁当類 - 20 -CS001215000005 -20181021 -20170206 +8 +P040101009 +04 +0401 +040101 +498.0 +374.0 +弁当類 - @@ -19155,18 +21044,24 @@21 -CS001215000040 -20171022 -20170214 +9 +P040101010 +04 +0401 +040101 +580.0 +435.0 +弁当類 演習問題
-P-027: レシート明細データフレーム(df_receipt)に対し、店舗コード(store_cd)ごとに売上金額(amount)の平均を計算し、降順でTOP5を表示せよ。
+P-038: 顧客データ(df_customer)とレシート明細データ(df_receipt)から、顧客ごとの売上金額合計を求め、10件表示せよ。ただし、売上実績がない顧客については売上金額を0として表示させること。また、顧客は性別コード(gender_cd)が女性(1)であるものを対象とし、非会員(顧客IDが"Z"から始まるもの)は除外すること。
- -- --- -In [28]:+In [43]:- ---@@ -19182,7 +21077,7 @@df_receipt.groupby('store_cd').agg({'amount':'mean'}).reset_index(). \ - sort_values('amount', ascending=False).head(5) +df_amount_sum = df_receipt.groupby('customer_id').amount.sum().reset_index() + +df_tmp = df_customer. \ + query('gender_cd == "1" and not customer_id.str.startswith("Z")', + engine='python') + +pd.merge(df_tmp['customer_id'], df_amount_sum, + how='left', on='customer_id').fillna(0).head(10)演習問題 -
Out[28]:+Out[43]:@@ -19205,130 +21100,60 @@演習問題
- store_cd +customer_id amount - -28 -S13052 -402.867470 -- -12 -S13015 -351.111960 -- -7 -S13003 -350.915519 -- 30 -S14010 -348.791262 +0 +CS021313000114 +0.0 - - - -5 -S13001 -348.470386 ----
-- -P-028: レシート明細データフレーム(df_receipt)に対し、店舗コード(store_cd)ごとに売上金額(amount)の中央値を計算し、降順でTOP5を表示せよ。
---- ---In [29]:------ -df_receipt.groupby('store_cd').agg({'amount':'median'}).reset_index(). \ - sort_values('amount', ascending=False).head(5) -- - -- -- - -Out[29]:- - - --- -- -
@@ -19345,18 +21170,27 @@- - -- store_cd -amount +1 +CS031415000172 +5088.0 - 28 -S13052 -190.0 +2 +CS028811000001 +0.0 - 30 -S14010 -188.0 +3 +CS001215000145 +875.0 - 51 -S14050 -185.0 +4 +CS015414000103 +3122.0 - +44 -S14040 -180.0 +5 +CS033513000180 +868.0 ++ 6 +CS035614000014 +0.0 + 7 -S13003 -180.0 +CS011215000048 +3444.0 ++ +8 +CS009413000079 +0.0 ++ 9 +CS040412000191 +210.0 演習問題
-P-029: レシート明細データフレーム(df_receipt)に対し、店舗コード(store_cd)ごとに商品コード(product_cd)の最頻値を求めよ。
+P-039: レシート明細データ(df_receipt)から、売上日数の多い顧客の上位20件を抽出したデータと、売上金額合計の多い顧客の上位20件を抽出したデータをそれぞれ作成し、さらにその2つを完全外部結合せよ。ただし、非会員(顧客IDが"Z"から始まるもの)は除外すること。
-In [30]:+In [44]:-@@ -19372,7 +21206,7 @@df_receipt.groupby('store_cd').product_cd. \ - apply(lambda x: x.mode()).reset_index() +df_data = df_receipt \ + .query('not customer_id.str.startswith("Z")', engine='python') + +df_cnt = df_data[~df_data.duplicated(subset=['customer_id', 'sales_ymd'])] \ + .groupby('customer_id').sales_ymd.count().reset_index() \ + .sort_values('sales_ymd', ascending=False).head(20) + +df_sum = df_data.groupby('customer_id').amount.sum().reset_index() \ + .sort_values('amount', ascending=False).head(20) + +pd.merge(df_cnt, df_sum, how='outer', on='customer_id')演習問題 -
Out[30]:+Out[44]:@@ -19395,341 +21229,215 @@演習問題
- store_cd -level_1 -product_cd +customer_id +sales_ymd +amount 0 -S12007 -0 -P060303001 +CS040214000008 +23.0 +NaN 1 -S12013 -0 -P060303001 +CS015415000185 +22.0 +20153.0 2 -S12014 -0 -P060303001 +CS010214000010 +22.0 +18585.0 3 -S12029 -0 -P060303001 +CS010214000002 +21.0 +NaN 4 -S12030 -0 -P060303001 +CS028415000007 +21.0 +19127.0 5 -S13001 -0 -P060303001 +CS017415000097 +20.0 +23086.0 6 -S13002 -0 -P060303001 +CS016415000141 +20.0 +18372.0 7 -S13003 -0 -P071401001 +CS031414000051 +19.0 +19202.0 8 -S13004 -0 -P060303001 +CS014214000023 +19.0 +NaN 9 -S13005 -0 -P040503001 +CS022515000226 +19.0 +NaN 10 -S13008 -0 -P060303001 +CS021515000172 +19.0 +NaN 11 -S13009 -0 -P060303001 +CS039414000052 +19.0 +NaN - 12 -S13015 -0 -P071401001 -- -13 -S13016 -0 -P071102001 -- -14 -S13017 -0 -P060101002 -- -15 -S13018 -0 -P071401001 -- -16 -S13019 -0 -P071401001 -- -17 -S13020 -0 -P071401001 -- -18 -S13031 -0 -P060303001 -- -19 -S13032 -0 -P060303001 -- -20 -S13035 -0 -P040503001 -- -21 -S13037 -0 -P060303001 -- -22 -S13038 -0 -P060303001 -- -23 -S13039 -0 -P071401001 -- -24 -S13041 -0 -P071401001 -- -25 -S13043 -0 -P060303001 -- -26 -S13044 -0 -P060303001 -- -27 -S13051 -0 -P050102001 -- -28 -S13051 -1 -P071003001 -- -29 -S13051 -2 -P080804001 -- -30 -S13052 -0 -P050101001 -- -31 -S14006 -0 -P060303001 -- -32 -S14010 -0 -P060303001 -- 33 -S14011 -0 -P060101001 +CS021514000045 +19.0 +NaN - 34 -S14012 -0 -P060303001 +13 +CS022515000028 +18.0 +NaN - 35 -S14021 -0 -P060101001 +14 +CS030214000008 +18.0 +NaN - 36 -S14022 -0 -P060303001 +15 +CS021515000056 +18.0 +NaN - 37 -S14023 -0 -P071401001 +16 +CS014415000077 +18.0 +NaN - 38 -S14024 -0 -P060303001 +17 +CS021515000211 +18.0 +NaN - 39 -S14025 -0 -P060303001 +18 +CS032415000209 +18.0 +NaN - 40 -S14026 -0 -P071401001 +19 +CS031414000073 +18.0 +NaN - 41 -S14027 -0 -P060303001 +20 +CS001605000009 +NaN +18925.0 - 42 -S14028 -0 -P060303001 +21 +CS006515000023 +NaN +18372.0 - 43 -S14033 -0 -P071401001 +22 +CS011414000106 +NaN +18338.0 - 44 -S14034 -0 -P060303001 +23 +CS038415000104 +NaN +17847.0 - 45 -S14036 -0 -P040503001 +24 +CS035414000024 +NaN +17615.0 - 46 -S14036 -1 -P060101001 +25 +CS021515000089 +NaN +17580.0 - 47 -S14040 -0 -P060303001 +26 +CS032414000072 +NaN +16563.0 - 48 -S14042 -0 -P050101001 +27 +CS016415000101 +NaN +16348.0 - 49 -S14045 -0 -P060303001 +28 +CS011415000006 +NaN +16094.0 - 50 -S14046 -0 -P060303001 +29 +CS034415000047 +NaN +16083.0 - 51 -S14047 -0 -P060303001 +30 +CS007514000094 +NaN +15735.0 - 52 -S14048 -0 -P050101001 +31 +CS009414000059 +NaN +15492.0 - 53 -S14049 -0 -P060303001 +32 +CS030415000034 +NaN +15468.0 - @@ -19746,18 +21454,23 @@54 -S14050 -0 -P060303001 +33 +CS015515000034 +NaN +15300.0 演習問題
-P-030: レシート明細データフレーム(df_receipt)に対し、店舗コード(store_cd)ごとに売上金額(amount)の標本分散を計算し、降順でTOP5を表示せよ。
+P-040: 全ての店舗と全ての商品を組み合わせたデータを作成したい。店舗データ(df_store)と商品データ(df_product)を直積し、件数を計算せよ。
-In [31]:+In [45]:--@@ -19773,62 +21486,13 @@df_receipt.groupby('store_cd').amount.var(ddof=0).reset_index(). \ - sort_values('amount', ascending=False).head(5) +df_store_tmp = df_store.copy() +df_product_tmp = df_product.copy() + +df_store_tmp['key'] = 0 +df_product_tmp['key'] = 0 + +len(pd.merge(df_store_tmp, df_product_tmp, how='outer', on='key'))演習問題 -
Out[31]:- +Out[45]:--@@ -19841,30 +21505,28 @@- -+- -
-- - - -- store_cd -amount -- -28 -S13052 -440088.701311 -- -31 -S14011 -306314.558164 -- -42 -S14034 -296920.081011 -- -5 -S13001 -295431.993329 -- - -12 -S13015 -295294.361116 -+531590演習問題
-
-P-031: レシート明細データフレーム(df_receipt)に対し、店舗コード(store_cd)ごとに売上金額(amount)の標本標準偏差を計算し、降順でTOP5を表示せよ。
+P-041: レシート明細データ(df_receipt)の売上金額(amount)を日付(sales_ymd)ごとに集計し、前回売上があった日からの売上金額増減を計算せよ。そして結果を10件表示せよ。
--TIPS:
-PandasとNumpyでddofのデフォルト値が異なることに注意しましょう
++++In [46]:+++-df_sales_amount_by_date = df_receipt[['sales_ymd', 'amount']].\ + groupby('sales_ymd').sum().reset_index() -+df_sales_amount_by_date = pd.concat([df_sales_amount_by_date, + df_sales_amount_by_date.shift()], axis=1) + +df_sales_amount_by_date.columns = ['sales_ymd','amount','lag_ymd','lag_amount'] + +df_sales_amount_by_date['diff_amount'] = \ + df_sales_amount_by_date['amount'] - df_sales_amount_by_date['lag_amount'] -Pandas: -DataFrame.std(self, axis=None, skipna=None, level=None, ddof=1, numeric_only=None, **kwargs) -Numpy: -numpy.std(a, axis=None, dtype=None, out=None, ddof=0, keepdims=)
---In [32]:---@@ -19880,7 +21542,7 @@df_receipt.groupby('store_cd').amount.std(ddof=0).reset_index(). \ - sort_values('amount', ascending=False).head(5) +df_sales_amount_by_date.head(10)演習問題 -
Out[32]:+Out[46]:@@ -19903,35 +21565,93 @@演習問題
- store_cd +sales_ymd amount +lag_ymd +lag_amount +diff_amount - 28 -S13052 -663.391816 +0 +20170101 +33723 +NaN +NaN +NaN - 31 -S14011 -553.456916 +1 +20170102 +24165 +20170101.0 +33723.0 +-9558.0 - +42 -S14034 -544.903736 +2 +20170103 +27503 +20170102.0 +24165.0 +3338.0 ++ +3 +20170104 +36165 +20170103.0 +27503.0 +8662.0 ++ 4 +20170105 +37830 +20170104.0 +36165.0 +1665.0 5 -S13001 -543.536561 +20170106 +32387 +20170105.0 +37830.0 +-5443.0 - +12 -S13015 -543.409938 +6 +20170107 +23415 +20170106.0 +32387.0 +-8972.0 ++ +7 +20170108 +24737 +20170107.0 +23415.0 +1322.0 ++ +8 +20170109 +26718 +20170108.0 +24737.0 +1981.0 ++ @@ -19948,56 +21668,31 @@9 +20170110 +20143 +20170109.0 +26718.0 +-6575.0 演習問題
-P-032: レシート明細データフレーム(df_receipt)の売上金額(amount)について、25%刻みでパーセンタイル値を求めよ。
+P-042: レシート明細データ(df_receipt)の売上金額(amount)を日付(sales_ymd)ごとに集計し、各日付のデータに対し、前回、前々回、3回前に売上があった日のデータを結合せよ。そして結果を10件表示せよ。
- ---In [33]:+In [47]:---- -# コード例1 -np.percentile(df_receipt['amount'], q=[25, 50, 75,100]) -- - -- -+df_lag.columns = ['sales_ymd', 'amount', 'lag_ymd', 'lag_amount'] -- - -+Out[33]:- - - - --- -array([ 102., 170., 288., 10925.])-+for i in range(1, 4): + df_tmp = pd.concat([df_sales_amount_by_date, + df_sales_amount_by_date.shift(i)], axis=1) + if i == 1: + df_lag = df_tmp + else: + df_lag = df_lag.append(df_tmp) -# コード例1:縦持ちケース +df_sales_amount_by_date = df_receipt[['sales_ymd', 'amount']]. \ + groupby('sales_ymd').sum().reset_index() ----+In [34]:----@@ -20013,42 +21708,135 @@# コード例2 -df_receipt.amount.quantile(q=np.arange(5)/4) +df_lag.dropna().astype(int).sort_values(['sales_ymd','lag_ymd']).head(10)演習問題 -
Out[34]:- +Out[47]:--+0.00 10.0 -0.25 102.0 -0.50 170.0 -0.75 288.0 -1.00 10925.0 -Name: amount, dtype: float64-+-+ +-+ +
+ + + ++ sales_ymd +amount +lag_ymd +lag_amount ++ +1 +20170102 +24165 +20170101 +33723 ++ +2 +20170103 +27503 +20170101 +33723 ++ +2 +20170103 +27503 +20170102 +24165 ++ +3 +20170104 +36165 +20170101 +33723 ++ +3 +20170104 +36165 +20170102 +24165 ++ +3 +20170104 +36165 +20170103 +27503 ++ +4 +20170105 +37830 +20170102 +24165 ++ +4 +20170105 +37830 +20170103 +27503 ++ +4 +20170105 +37830 +20170104 +36165 ++ + +5 +20170106 +32387 +20170103 +27503 +--+ +
-+P-033: レシート明細データフレーム(df_receipt)に対し、店舗コード(store_cd)ごとに売上金額(amount)の平均を計算し、330以上のものを抽出せよ。
--In [35]:+In [48]:-@@ -20064,7 +21852,7 @@df_receipt.groupby('store_cd').amount.mean(). \ - reset_index().query('amount >= 330') +# コード例2:横持ちケース +df_sales_amount_by_date = df_receipt[['sales_ymd', 'amount']].\ + groupby('sales_ymd').sum().reset_index() + +df_lag = df_sales_amount_by_date + +for i in range(1, 4): + df_lag = pd.concat([df_lag, df_sales_amount_by_date.shift(i)], axis=1) + columns = [f'lag_ymd_{i}', f'lag_amount_{i}'] + df_lag.columns = list(df_lag.columns)[:-len(columns)] + columns + +df_lag.dropna().astype(int).sort_values(['sales_ymd']).head(10)演習問題 -
Out[35]:+Out[48]:@@ -20087,75 +21875,126 @@演習問題
- store_cd +sales_ymd amount +lag_ymd_1 +lag_amount_1 +lag_ymd_2 +lag_amount_2 +lag_ymd_3 +lag_amount_3 - -1 -S12013 -330.194130 -- -5 -S13001 -348.470386 -- -7 -S13003 -350.915519 -- 8 -S13004 -330.943949 +3 +20170104 +36165 +20170103 +27503 +20170102 +24165 +20170101 +33723 - 12 -S13015 -351.111960 +4 +20170105 +37830 +20170104 +36165 +20170103 +27503 +20170102 +24165 - 16 -S13019 -330.208616 +5 +20170106 +32387 +20170105 +37830 +20170104 +36165 +20170103 +27503 - 17 -S13020 -337.879932 +6 +20170107 +23415 +20170106 +32387 +20170105 +37830 +20170104 +36165 - 28 -S13052 -402.867470 +7 +20170108 +24737 +20170107 +23415 +20170106 +32387 +20170105 +37830 - 30 -S14010 -348.791262 +8 +20170109 +26718 +20170108 +24737 +20170107 +23415 +20170106 +32387 - 31 -S14011 -335.718333 +9 +20170110 +20143 +20170109 +26718 +20170108 +24737 +20170107 +23415 - 38 -S14026 -332.340588 +10 +20170111 +24287 +20170110 +20143 +20170109 +26718 +20170108 +24737 - 46 -S14045 -330.082073 +11 +20170112 +23526 +20170111 +24287 +20170110 +20143 +20170109 +26718 - @@ -20172,19 +22011,32 @@48 -S14047 -330.077073 +12 +20170113 +28004 +20170112 +23526 +20170111 +24287 +20170110 +20143 演習問題
-P-034: レシート明細データフレーム(df_receipt)に対し、顧客ID(customer_id)ごとに売上金額(amount)を合計して全顧客の平均を求めよ。ただし、顧客IDが"Z"から始まるのものは非会員を表すため、除外して計算すること。
+P-043: レシート明細データ(df_receipt)と顧客データ(df_customer)を結合し、性別コード(gender_cd)と年代(ageから計算)ごとに売上金額(amount)を合計した売上サマリデータを作成せよ。性別コードは0が男性、1が女性、9が不明を表すものとする。
+ただし、項目構成は年代、女性の売上金額、男性の売上金額、性別不明の売上金額の4項目とすること(縦に年代、横に性別のクロス集計)。また、年代は10歳ごとの階級とすること。
-In [36]:+In [49]:-@@ -20218,60 +22159,20 @@@@ -20200,13 +22052,102 @@# queryを使わない書き方 -df_receipt[~df_receipt['customer_id'].str.startswith("Z")]. \ - groupby('customer_id').amount.sum().mean() +# コード例1 +df_tmp = pd.merge(df_receipt, df_customer, how ='inner', on="customer_id") + +df_tmp['era'] = df_tmp['age'].apply(lambda x: math.floor(x / 10) * 10) + +df_sales_summary = pd.pivot_table( + df_tmp, index='era', + columns='gender_cd', + values='amount', + aggfunc='sum' + ).reset_index() + +df_sales_summary.columns = ['era', 'male', 'female', 'unknown'] + +df_sales_summary演習問題 -
Out[36]:+Out[49]:+ +++ ++ +
++ + + ++ era +male +female +unknown ++ +0 +10 +1591.0 +149836.0 +4317.0 ++ +1 +20 +72940.0 +1363724.0 +44328.0 ++ +2 +30 +177322.0 +693047.0 +50441.0 ++ +3 +40 +19355.0 +9320791.0 +483512.0 ++ +4 +50 +54320.0 +6685192.0 +342923.0 ++ +5 +60 +272469.0 +987741.0 +71418.0 ++ +6 +70 +13435.0 +29764.0 +2427.0 ++ +7 +80 +46360.0 +262923.0 +5111.0 ++ + +8 +90 +NaN +6260.0 +NaN +演習問題
- ---In [37]:+In [50]:---- -# queryを使う書き方 -df_receipt.query('not customer_id.str.startswith("Z")', - engine='python').groupby('customer_id').amount.sum().mean() -- - --- -+df_sales_summary = pd.pivot_table(df_tmp, index='era', columns='gender_cd', + values='amount', aggfunc='sum').reset_index() -- - -+Out[37]:- - - - --- -2547.742234529256-+df_tmp['era'] = np.floor(df_tmp['age'] / 10).astype(int) * 10 -# コード例2 +df_tmp = pd.merge(df_receipt, df_customer, how ='inner', on="customer_id") ----
-+df_sales_summary.columns = ['era', 'male', 'female', 'unknown'] -P-035: レシート明細データフレーム(df_receipt)に対し、顧客ID(customer_id)ごとに売上金額(amount)を合計して全顧客の平均を求め、平均以上に買い物をしている顧客を抽出せよ。ただし、顧客IDが"Z"から始まるのものは非会員を表すため、除外して計算すること。なお、データは10件だけ表示させれば良い。
----In [38]:---@@ -20287,7 +22188,7 @@df_receipt_tmp = df_receipt[~df_receipt['customer_id'].str.startswith("Z")] -amount_mean = df_receipt_tmp.groupby('customer_id').amount.sum().mean() -df_amount_sum = df_receipt_tmp.groupby('customer_id').amount.sum().reset_index() -df_amount_sum[df_amount_sum['amount'] >= amount_mean].head(10) +df_sales_summary演習問題 -
Out[38]:+Out[50]:@@ -20310,60 +22211,75 @@演習問題
- customer_id -amount +era +male +female +unknown - -2 -CS001115000010 -3044 -- 4 -CS001205000006 -3337 +0 +10 +1591.0 +149836.0 +4317.0 - 13 -CS001214000009 -4685 +1 +20 +72940.0 +1363724.0 +44328.0 - 14 -CS001214000017 -4132 +2 +30 +177322.0 +693047.0 +50441.0 - 17 -CS001214000052 -5639 +3 +40 +19355.0 +9320791.0 +483512.0 - 21 -CS001215000040 -3496 +4 +50 +54320.0 +6685192.0 +342923.0 - 30 -CS001304000006 -3726 +5 +60 +272469.0 +987741.0 +71418.0 - 32 -CS001305000005 -3485 +6 +70 +13435.0 +29764.0 +2427.0 - 33 -CS001305000011 -4370 +7 +80 +46360.0 +262923.0 +5111.0 - @@ -20380,18 +22296,19 @@53 -CS001315000180 -3300 +8 +90 +NaN +6260.0 +NaN 演習問題
-P-036: レシート明細データフレーム(df_receipt)と店舗データフレーム(df_store)を内部結合し、レシート明細データフレームの全項目と店舗データフレームの店舗名(store_name)を10件表示させよ。
+P-044: 043で作成した売上サマリデータ(df_sales_summary)は性別の売上を横持ちさせたものであった。このデータから性別を縦持ちさせ、年代、性別コード、売上金額の3項目に変換せよ。ただし、性別コードは男性を"00"、女性を"01"、不明を"99"とする。
-In [39]:+In [51]:-@@ -20407,7 +22324,7 @@pd.merge(df_receipt, df_store[['store_cd','store_name']], - how='inner', on='store_cd').head(10) +df_sales_summary.set_index('era'). \ + stack().reset_index().replace({'female':'01','male':'00','unknown':'99'}). \ + rename(columns={'level_1':'gender_cd', 0: 'amount'})演習問題 -
Out[39]:+Out[51]:@@ -20430,148 +22347,161 @@演習問題
- sales_ymd -sales_epoch -store_cd -receipt_no -receipt_sub_no -customer_id -product_cd -quantity +era +gender_cd amount -store_name + 0 -20181103 -1541203200 -S14006 -112 -1 -CS006214000001 -P070305012 -1 -158 -葛が谷店 +10 +00 +1591.0 ++ +1 +10 +01 +149836.0 ++ +2 +10 +99 +4317.0 ++ +3 +20 +00 +72940.0 ++ +4 +20 +01 +1363724.0 ++ +5 +20 +99 +44328.0 ++ +6 +30 +00 +177322.0 ++ +7 +30 +01 +693047.0 ++ +8 +30 +99 +50441.0 ++ +9 +40 +00 +19355.0 ++ +10 +40 +01 +9320791.0 ++ +11 +40 +99 +483512.0 ++ +12 +50 +00 +54320.0 ++ 13 +50 +01 +6685192.0 - 1 -20181116 -1542326400 -S14006 -112 -2 -ZZ000000000000 -P080401001 -1 -48 -葛が谷店 +14 +50 +99 +342923.0 - 2 -20170118 -1484697600 -S14006 -1162 -1 -CS006815000006 -P050406035 -1 -220 -葛が谷店 +15 +60 +00 +272469.0 - 3 -20190524 -1558656000 -S14006 -1192 -1 -CS006514000034 -P060104003 -1 -80 -葛が谷店 +16 +60 +01 +987741.0 - 4 -20190419 -1555632000 -S14006 -112 -2 -ZZ000000000000 -P060501002 -1 -148 -葛が谷店 +17 +60 +99 +71418.0 - 5 -20181119 -1542585600 -S14006 -1152 -2 -ZZ000000000000 -P050701001 -1 -88 -葛が谷店 +18 +70 +00 +13435.0 - +6 -20171211 -1512950400 -S14006 -1132 -2 -CS006515000175 -P090903001 -1 +19 +70 +01 +29764.0 ++ +20 +70 +99 +2427.0 ++ 21 80 -葛が谷店 +00 +46360.0 - 7 -20191021 -1571616000 -S14006 -1112 -2 -CS006415000221 -P040602001 -1 -405 -葛が谷店 +22 +80 +01 +262923.0 - 8 -20170710 -1499644800 -S14006 -1132 -2 -CS006411000036 -P090301051 -1 -330 -葛が谷店 +23 +80 +99 +5111.0 - @@ -20588,19 +22518,22 @@9 -20190805 -1564963200 -S14006 -112 -1 -CS006211000012 -P050104001 -1 -115 -葛が谷店 +24 +90 +01 +6260.0 演習問題
-P-037: 商品データフレーム(df_product)とカテゴリデータフレーム(df_category)を内部結合し、商品データフレームの全項目とカテゴリデータフレームの小区分名(category_small_name)を10件表示させよ。
+P-045: 顧客データ(df_customer)の生年月日(birth_day)は日付型でデータを保有している。これをYYYYMMDD形式の文字列に変換し、顧客ID(customer_id)とともに10件表示せよ。
-In [40]:+In [52]:-@@ -20616,7 +22549,7 @@pd.merge(df_product - , df_category[['category_small_cd','category_small_name']] - , how='inner', on='category_small_cd').head(10) +# 以下の書き方でYYYYMMDD形式の文字列に変換できる +# pd.to_datetime(df_customer['birth_day']).dt.strftime('%Y%m%d') + +pd.concat([df_customer['customer_id'], + pd.to_datetime(df_customer['birth_day']).dt.strftime('%Y%m%d')], + axis = 1).head(10)演習問題 -
Out[40]:+Out[52]:@@ -20639,115 +22572,60 @@演習問題
- product_cd -category_major_cd -category_medium_cd -category_small_cd -unit_price -unit_cost -category_small_name +customer_id +birth_day 0 -P040101001 -04 -0401 -040101 -198.0 -149.0 -弁当類 +CS021313000114 +19810429 1 -P040101002 -04 -0401 -040101 -218.0 -164.0 -弁当類 +CS037613000071 +19520401 2 -P040101003 -04 -0401 -040101 -230.0 -173.0 -弁当類 +CS031415000172 +19761004 3 -P040101004 -04 -0401 -040101 -248.0 -186.0 -弁当類 +CS028811000001 +19330327 4 -P040101005 -04 -0401 -040101 -268.0 -201.0 -弁当類 +CS001215000145 +19950329 5 -P040101006 -04 -0401 -040101 -298.0 -224.0 -弁当類 +CS020401000016 +19740915 6 -P040101007 -04 -0401 -040101 -338.0 -254.0 -弁当類 +CS015414000103 +19770809 7 -P040101008 -04 -0401 -040101 -420.0 -315.0 -弁当類 +CS029403000008 +19730817 8 -P040101009 -04 -0401 -040101 -498.0 -374.0 -弁当類 +CS015804000004 +19310502 @@ -20764,22 +22642,18 @@ 9 -P040101010 -04 -0401 -040101 -580.0 -435.0 -弁当類 +CS033513000180 +19620711 演習問題
-P-038: 顧客データフレーム(df_customer)とレシート明細データフレーム(df_receipt)から、各顧客ごとの売上金額合計を求めよ。ただし、売上実績がない顧客については売上金額を0として表示させること。また、顧客は性別コード(gender_cd)が女性(1)であるものを対象とし、非会員(顧客IDが"Z"から始まるもの)は除外すること。なお、結果は10件だけ表示させれば良い。
+P-046: 顧客データ(df_customer)の申し込み日(application_date)はYYYYMMDD形式の文字列型でデータを保有している。これを日付型に変換し、顧客ID(customer_id)とともに10件表示せよ。
-In [41]:+In [53]:-@@ -20795,7 +22669,7 @@df_amount_sum = df_receipt.groupby('customer_id').amount.sum().reset_index() -df_tmp = df_customer. \ - query('gender_cd == "1" and not customer_id.str.startswith("Z")', - engine='python') -pd.merge(df_tmp['customer_id'], df_amount_sum, - how='left', on='customer_id').fillna(0).head(10) +pd.concat([df_customer['customer_id'], + pd.to_datetime(df_customer['application_date'])], axis=1).head(10)演習問題 -
Out[41]:+Out[53]:@@ -20819,59 +22693,59 @@演習問題
customer_id -amount +application_date 0 CS021313000114 -0.0 +2015-09-05 1 -CS031415000172 -5088.0 +CS037613000071 +2015-04-14 2 -CS028811000001 -0.0 +CS031415000172 +2015-05-29 3 -CS001215000145 -875.0 +CS028811000001 +2016-01-15 4 -CS015414000103 -3122.0 +CS001215000145 +2017-06-05 5 -CS033513000180 -868.0 +CS020401000016 +2015-02-25 6 -CS035614000014 -0.0 +CS015414000103 +2015-07-22 7 -CS011215000048 -3444.0 +CS029403000008 +2015-05-15 8 -CS009413000079 -0.0 +CS015804000004 +2015-06-07 @@ -20888,26 +22762,19 @@ 9 -CS040412000191 -210.0 +CS033513000180 +2015-07-28 演習問題
-P-039: レシート明細データフレーム(df_receipt)から売上日数の多い顧客の上位20件と、売上金額合計の多い顧客の上位20件を抽出し、完全外部結合せよ。ただし、非会員(顧客IDが"Z"から始まるもの)は除外すること。
+P-047: レシート明細データ(df_receipt)の売上エポック秒(sales_epoch)は数値型のUNIX秒でデータを保有している。これを日付型に変換し、レシート番号(receipt_no)、レシートサブ番号(receipt_sub_no)とともに10件表示せよ。
-In [42]:+In [54]:-@@ -20923,7 +22790,7 @@df_sum = df_receipt.groupby('customer_id').amount.sum().reset_index() -df_sum = df_sum.query('not customer_id.str.startswith("Z")', engine='python') -df_sum = df_sum.sort_values('amount', ascending=False).head(20) - -df_cnt = df_receipt[~df_receipt.duplicated(subset=['customer_id', 'sales_ymd'])] -df_cnt = df_cnt.query('not customer_id.str.startswith("Z")', engine='python') -df_cnt = df_cnt.groupby('customer_id').sales_ymd.count().reset_index() -df_cnt = df_cnt.sort_values('sales_ymd', ascending=False).head(20) - -pd.merge(df_sum, df_cnt, how='outer', on='customer_id') +pd.concat([df_receipt[['receipt_no', 'receipt_sub_no']], + pd.to_datetime(df_receipt['sales_ymd'].astype('str'))], + axis=1).head(10)演習問題 -
Out[42]:+Out[54]:@@ -20946,215 +22813,71 @@演習問題
- customer_id -amount +receipt_no +receipt_sub_no sales_ymd 0 -CS017415000097 -23086.0 -20.0 +112 +1 +2018-11-03 1 -CS015415000185 -20153.0 -22.0 +1132 +2 +2018-11-18 2 -CS031414000051 -19202.0 -19.0 +1102 +1 +2017-07-12 3 -CS028415000007 -19127.0 -21.0 +1132 +1 +2019-02-05 4 -CS001605000009 -18925.0 -NaN +1102 +2 +2018-08-21 5 -CS010214000010 -18585.0 -22.0 +1112 +1 +2019-06-05 - 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 +1102 +2 +2018-12-05 - 32 -CS032415000209 -NaN -18.0 +7 +1102 +1 +2019-09-22 - +33 -CS031414000073 -NaN -18.0 +8 +1112 +2 +2017-05-04 ++ @@ -21171,74 +22894,19 @@9 +1102 +1 +2019-10-10 演習問題
-
-- -P-040: 全ての店舗と全ての商品を組み合わせると何件のデータとなるか調査したい。店舗(df_store)と商品(df_product)を直積した件数を計算せよ。
----- ---In [43]:------ -df_store_tmp = df_store.copy() -df_product_tmp = df_product.copy() - -df_store_tmp['key'] = 0 -df_product_tmp['key'] = 0 -len(pd.merge(df_store_tmp, df_product_tmp, how='outer', on='key')) -- - -- -- -- -- - -- -Out[43]:- - - - --- -531590---
-P-041: レシート明細データフレーム(df_receipt)の売上金額(amount)を日付(sales_ymd)ごとに集計し、前日からの売上金額増減を計算せよ。なお、計算結果は10件表示すればよい。
+P-048: レシート明細データフレーム(df_receipt)の売上エポック秒(sales_epoch)は数値型のUNIX秒でデータを保有している。これを日付型に変換し、レシート番号(receipt_no)、レシートサブ番号(receipt_sub_no)とともに10件表示せよ。
-In [44]:+In [55]:-@@ -21254,7 +22922,7 @@df_sales_amount_by_date = df_receipt[['sales_ymd', 'amount']].\ - groupby('sales_ymd').sum().reset_index() -df_sales_amount_by_date = pd.concat([df_sales_amount_by_date, - df_sales_amount_by_date.shift()], axis=1) -df_sales_amount_by_date.columns = ['sales_ymd','amount','lag_ymd','lag_amount'] -df_sales_amount_by_date['diff_amount'] = \ - df_sales_amount_by_date['amount'] - df_sales_amount_by_date['lag_amount'] -df_sales_amount_by_date.head(10) +pd.concat([df_receipt[['receipt_no', 'receipt_sub_no']], + pd.to_datetime(df_receipt['sales_epoch'], unit='s').rename('sales_ymd')], + axis=1).head(10)演習問題 -
Out[44]:+Out[55]:@@ -21277,93 +22945,71 @@演習問題
+ receipt_no +receipt_sub_no sales_ymd -amount -lag_ymd -lag_amount -diff_amount 0 -20170101 -33723 -NaN -NaN -NaN +112 +1 +2018-11-03 1 -20170102 -24165 -20170101.0 -33723.0 --9558.0 +1132 +2 +2018-11-18 2 -20170103 -27503 -20170102.0 -24165.0 -3338.0 +1102 +1 +2017-07-12 3 -20170104 -36165 -20170103.0 -27503.0 -8662.0 +1132 +1 +2019-02-05 4 -20170105 -37830 -20170104.0 -36165.0 -1665.0 +1102 +2 +2018-08-21 5 -20170106 -32387 -20170105.0 -37830.0 --5443.0 +1112 +1 +2019-06-05 6 -20170107 -23415 -20170106.0 -32387.0 --8972.0 +1102 +2 +2018-12-05 7 -20170108 -24737 -20170107.0 -23415.0 -1322.0 +1102 +1 +2019-09-22 8 -20170109 -26718 -20170108.0 -24737.0 -1981.0 +1112 +2 +2017-05-04 @@ -21380,29 +23026,20 @@ 9 -20170110 -20143 -20170109.0 -26718.0 --6575.0 +1102 +1 +2019-10-10 演習問題
-P-042: レシート明細データフレーム(df_receipt)の売上金額(amount)を日付(sales_ymd)ごとに集計し、各日付のデータに対し、1日前、2日前、3日前のデータを結合せよ。結果は10件表示すればよい。
+P-049: レシート明細データ(df_receipt)の売上エポック秒(sales_epoch)を日付型に変換し、「年」だけ取り出してレシート番号(receipt_no)、レシートサブ番号(receipt_sub_no)とともに10件表示せよ。
-In [45]:+In [56]:-+@@ -21418,7 +23055,7 @@# コード例1:縦持ちケース -df_sales_amount_by_date = df_receipt[['sales_ymd', 'amount']]. \ - groupby('sales_ymd').sum().reset_index() -for i in range(1, 4): - if i == 1: - df_lag = pd.concat([df_sales_amount_by_date, - df_sales_amount_by_date.shift(i)],axis=1) - else: - df_lag = df_lag.append(pd.concat([df_sales_amount_by_date, - df_sales_amount_by_date.shift(i)], - axis=1)) -df_lag.columns = ['sales_ymd', 'amount', 'lag_ymd', 'lag_amount'] -df_lag.dropna().sort_values(['sales_ymd','lag_ymd']).head(10) +pd.concat([df_receipt[['receipt_no', 'receipt_sub_no']], + pd.to_datetime(df_receipt['sales_epoch'], + unit='s').dt.year.rename('sales_year')], + axis=1).head(10)演習問題 -
Out[45]:+Out[56]:@@ -21441,82 +23078,71 @@演習問題
- sales_ymd -amount -lag_ymd -lag_amount +receipt_no +receipt_sub_no +sales_year - 1 -20170102 -24165 -20170101.0 -33723.0 +0 +112 +1 +2018 - 2 -20170103 -27503 -20170101.0 -33723.0 +1 +1132 +2 +2018 2 -20170103 -27503 -20170102.0 -24165.0 +1102 +1 +2017 3 -20170104 -36165 -20170101.0 -33723.0 +1132 +1 +2019 - 3 -20170104 -36165 -20170102.0 -24165.0 +4 +1102 +2 +2018 - 3 -20170104 -36165 -20170103.0 -27503.0 +5 +1112 +1 +2019 - 4 -20170105 -37830 -20170102.0 -24165.0 +6 +1102 +2 +2018 - 4 -20170105 -37830 -20170103.0 -27503.0 +7 +1102 +1 +2019 - 4 -20170105 -37830 -20170104.0 -36165.0 +8 +1112 +2 +2017 - @@ -21529,24 +23155,26 @@5 -20170106 -32387 -20170103.0 -27503.0 +9 +1102 +1 +2019 演習問題 +
++
++ +P-050: レシート明細データ(df_receipt)の売上エポック秒(sales_epoch)を日付型に変換し、「月」だけ取り出してレシート番号(receipt_no)、レシートサブ番号(receipt_sub_no)とともに10件表示せよ。なお、「月」は0埋め2桁で取り出すこと。
+-In [46]:+In [57]:-@@ -21562,7 +23190,7 @@# コード例2:横持ちケース -df_sales_amount_by_date = df_receipt[['sales_ymd', 'amount']].\ - groupby('sales_ymd').sum().reset_index() -for i in range(1, 4): - if i == 1: - df_lag = pd.concat([df_sales_amount_by_date, - df_sales_amount_by_date.shift(i)],axis=1) - else: - df_lag = pd.concat([df_lag, df_sales_amount_by_date.shift(i)],axis=1) -df_lag.columns = ['sales_ymd', 'amount', 'lag_ymd_1', 'lag_amount_1', - 'lag_ymd_2', 'lag_amount_2', 'lag_ymd_3', 'lag_amount_3'] -df_lag.dropna().sort_values(['sales_ymd']).head(10) +# dt.monthでも月を取得できるが、ここでは0埋め2桁で取り出すためstrftimeを利用している +df_datetime = pd.to_datetime(df_receipt['sales_epoch'], + unit='s').rename('sales_month') + +pd.concat([df_receipt[['receipt_no', 'receipt_sub_no']], + df_datetime.dt.strftime('%m')],axis=1).head(10)演習問題 -
Out[46]:+Out[57]:@@ -21585,126 +23213,71 @@演習問題
+ - sales_ymd -amount -lag_ymd_1 -lag_amount_1 -lag_ymd_2 -lag_amount_2 -lag_ymd_3 -lag_amount_3 +receipt_no +receipt_sub_no +sales_month + +0 +112 +1 +11 ++ +1 +1132 +2 +11 ++ 2 +1102 +1 +07 +3 -20170104 -36165 -20170103.0 -27503.0 -20170102.0 -24165.0 -20170101.0 -33723.0 +1132 +1 +02 4 -20170105 -37830 -20170104.0 -36165.0 -20170103.0 -27503.0 -20170102.0 -24165.0 +1102 +2 +08 5 -20170106 -32387 -20170105.0 -37830.0 -20170104.0 -36165.0 -20170103.0 -27503.0 +1112 +1 +06 6 -20170107 -23415 -20170106.0 -32387.0 -20170105.0 -37830.0 -20170104.0 -36165.0 +1102 +2 +12 7 -20170108 -24737 -20170107.0 -23415.0 -20170106.0 -32387.0 -20170105.0 -37830.0 +1102 +1 +09 8 -20170109 -26718 -20170108.0 -24737.0 -20170107.0 -23415.0 -20170106.0 -32387.0 +1112 +2 +05 - 9 -20170110 -20143 -20170109.0 -26718.0 -20170108.0 -24737.0 -20170107.0 -23415.0 -- -10 -20170111 -24287 -20170110.0 -20143.0 -20170109.0 -26718.0 -20170108.0 -24737.0 -- -11 -20170112 -23526 -20170111.0 -24287.0 -20170110.0 -20143.0 -20170109.0 -26718.0 -- @@ -21721,24 +23294,22 @@12 -20170113 -28004 -20170112.0 -23526.0 -20170111.0 -24287.0 -20170110.0 -20143.0 +1102 +1 +10 演習問題
-P-043: レシート明細データフレーム(df_receipt)と顧客データフレーム(df_customer)を結合し、性別(gender)と年代(ageから計算)ごとに売上金額(amount)を合計した売上サマリデータフレーム(df_sales_summary)を作成せよ。性別は0が男性、1が女性、9が不明を表すものとする。
-ただし、項目構成は年代、女性の売上金額、男性の売上金額、性別不明の売上金額の4項目とすること(縦に年代、横に性別のクロス集計)。また、年代は10歳ごとの階級とすること。
+P-051: レシート明細データ(df_receipt)の売上エポック秒を日付型に変換し、「日」だけ取り出してレシート番号(receipt_no)、レシートサブ番号(receipt_sub_no)とともに10件表示せよ。なお、「日」は0埋め2桁で取り出すこと。
-In [47]:+In [58]:-+@@ -21754,7 +23325,7 @@# コード例1 -df_tmp = pd.merge(df_receipt, df_customer, how ='inner', on="customer_id") -df_tmp['era'] = df_tmp['age'].apply(lambda x: math.floor(x / 10) * 10) -df_sales_summary = pd.pivot_table(df_tmp, index='era', columns='gender_cd', - values='amount', aggfunc='sum').reset_index() -df_sales_summary.columns = ['era', 'male', 'female', 'unknown'] -df_sales_summary +# dt.dayでも日を取得できるが、ここでは0埋め2桁で取り出すためstrftimeを利用している +df_datetime = pd.to_datetime(df_receipt['sales_epoch'], + unit='s').rename('sales_day') + +pd.concat([df_receipt[['receipt_no', 'receipt_sub_no']], + df_datetime.dt.strftime('%d')], axis=1).head(10)演習問題 -
Out[47]:+Out[58]:@@ -21777,75 +23348,71 @@演習問題
- era -male -female -unknown +receipt_no +receipt_sub_no +sales_day 0 -10 -1591.0 -149836.0 -4317.0 +112 +1 +03 1 -20 -72940.0 -1363724.0 -44328.0 +1132 +2 +18 2 -30 -177322.0 -693047.0 -50441.0 +1102 +1 +12 3 -40 -19355.0 -9320791.0 -483512.0 +1132 +1 +05 4 -50 -54320.0 -6685192.0 -342923.0 +1102 +2 +21 5 -60 -272469.0 -987741.0 -71418.0 +1112 +1 +05 6 -70 -13435.0 -29764.0 -2427.0 +1102 +2 +05 7 -80 -46360.0 -262923.0 -5111.0 +1102 +1 +22 + 8 -90 -NaN -6260.0 -NaN +1112 +2 +04 ++ @@ -21858,19 +23425,31 @@9 +1102 +1 +10 演習問題 +
++
++ +P-052: レシート明細データ(df_receipt)の売上金額(amount)を顧客ID(customer_id)ごとに合計の上、売上金額合計に対して2,000円以下を0、2,000円より大きい金額を1に二値化し、顧客ID、売上金額合計とともに10件表示せよ。ただし、顧客IDが"Z"から始まるのものは非会員を表すため、除外して計算すること。
+-In [48]:+In [59]:--@@ -21886,7 +23465,7 @@# コード例2 -df_tmp = pd.merge(df_receipt, df_customer, how ='inner', on="customer_id") -df_tmp['era'] = np.floor(df_tmp['age'] / 10).astype(int) * 10 -df_sales_summary = pd.pivot_table(df_tmp, index='era', columns='gender_cd', - values='amount', aggfunc='sum').reset_index() -df_sales_summary.columns = ['era', 'male', 'female', 'unknown'] -df_sales_summary +# コード例1 +df_sales_amount = df_receipt.query('not customer_id.str.startswith("Z")', + engine='python') + +df_sales_amount = df_sales_amount[['customer_id', 'amount']]. \ + groupby('customer_id').sum().reset_index() + +df_sales_amount['sales_flg'] = df_sales_amount['amount']. \ + apply(lambda x: 1 if x > 2000 else 0) + +df_sales_amount.head(10)演習問題 -
Out[48]:+Out[59]:@@ -21909,75 +23488,71 @@演習問題
- era -male -female -unknown +customer_id +amount +sales_flg 0 -10 -1591.0 -149836.0 -4317.0 +CS001113000004 +1298 +0 1 -20 -72940.0 -1363724.0 -44328.0 +CS001114000005 +626 +0 2 -30 -177322.0 -693047.0 -50441.0 +CS001115000010 +3044 +1 3 -40 -19355.0 -9320791.0 -483512.0 +CS001205000004 +1988 +0 4 -50 -54320.0 -6685192.0 -342923.0 +CS001205000006 +3337 +1 5 -60 -272469.0 -987741.0 -71418.0 +CS001211000025 +456 +0 6 -70 -13435.0 -29764.0 -2427.0 +CS001212000027 +448 +0 7 -80 -46360.0 -262923.0 -5111.0 +CS001212000031 +296 +0 + 8 -90 -NaN -6260.0 -NaN +CS001212000046 +228 +0 ++ @@ -21990,37 +23565,22 @@9 +CS001212000070 +456 +0 演習問題 -
---
-- -P-044: 前設問で作成した売上サマリデータフレーム(df_sales_summary)は性別の売上を横持ちさせたものであった。このデータフレームから性別を縦持ちさせ、年代、性別コード、売上金額の3項目に変換せよ。ただし、性別コードは男性を"00"、女性を"01"、不明を"99"とする。
-+-+df_sales_amount = df_sales_amount[['customer_id', 'amount']]. \ + groupby('customer_id').sum().reset_index() -In [49]:+In [60]:---+df_sales_summary = df_sales_summary.set_index('era'). \ - stack().reset_index().replace({'female':'01','male':'00','unknown':'99'}). \ - rename(columns={'level_1':'gender_cd', 0: 'amount'}) --# コード例2(np.whereの活用) +df_sales_amount = df_receipt.query('not customer_id.str.startswith("Z")', + engine='python') ----In [50]:---@@ -22036,7 +23596,7 @@df_sales_summary +df_sales_amount['sales_flg'] = np.where(df_sales_amount['amount'] > 2000, 1, 0) + +df_sales_amount.head(10)演習問題 -
Out[50]:+Out[60]:@@ -22059,161 +23619,71 @@演習問題
- era -gender_cd +customer_id amount +sales_flg 0 -10 -00 -1591.0 +CS001113000004 +1298 +0 1 -10 -01 -149836.0 +CS001114000005 +626 +0 2 -10 -99 -4317.0 +CS001115000010 +3044 +1 - 3 -20 -00 -72940.0 -- -4 -20 -01 -1363724.0 -- -5 -20 -99 -44328.0 -- -6 -30 -00 -177322.0 -- -7 -30 -01 -693047.0 -- -8 -30 -99 -50441.0 -- -9 -40 -00 -19355.0 -- -10 -40 -01 -9320791.0 -- -11 -40 -99 -483512.0 -- -12 -50 -00 -54320.0 -- -13 -50 -01 -6685192.0 -- -14 -50 -99 -342923.0 -- -15 -60 -00 -272469.0 -- -16 -60 -01 -987741.0 -- -17 -60 -99 -71418.0 -- 18 -70 -00 -13435.0 +CS001205000004 +1988 +0 - 19 -70 -01 -29764.0 +4 +CS001205000006 +3337 +1 - 20 -70 -99 -2427.0 +5 +CS001211000025 +456 +0 - 21 -80 -00 -46360.0 +6 +CS001212000027 +448 +0 - 22 -80 -01 -262923.0 +7 +CS001212000031 +296 +0 - 23 -80 -99 -5111.0 +8 +CS001212000046 +228 +0 - @@ -22230,19 +23700,24 @@24 -90 -01 -6260.0 +9 +CS001212000070 +456 +0 演習問題
-P-045: 顧客データフレーム(df_customer)の生年月日(birth_day)は日付型でデータを保有している。これをYYYYMMDD形式の文字列に変換し、顧客ID(customer_id)とともに抽出せよ。データは10件を抽出すれば良い。
+P-053: 顧客データ(df_customer)の郵便番号(postal_cd)に対し、東京(先頭3桁が100〜209のもの)を1、それ以外のものを0に二値化せよ。さらにレシート明細データ(df_receipt)と結合し、全期間において売上実績のある顧客数を、作成した二値ごとにカウントせよ。
+ ++ +-+ +In [51]:+In [61]:+ +-+@@ -22258,7 +23733,7 @@pd.concat([df_customer['customer_id'], - pd.to_datetime(df_customer['birth_day']).dt.strftime('%Y%m%d')], - axis = 1).head(10) +# コード例1 +df_tmp = df_customer[['customer_id', 'postal_cd']].copy() + +df_tmp['postal_flg'] = df_tmp['postal_cd']. \ + apply(lambda x: 1 if 100 <= int(x[0:3]) <= 209 else 0) + +pd.merge(df_tmp, df_receipt, how='inner', on='customer_id'). \ + groupby('postal_flg').agg({'customer_id':'nunique'})演習問題 -
Out[51]:+Out[61]:@@ -22282,59 +23757,99 @@演習問題
customer_id -birth_day + ++ postal_flg +0 -CS021313000114 -19810429 +3906 - 1 -CS037613000071 -19520401 -- -2 -CS031415000172 -19761004 -- -3 -CS028811000001 -19330327 -- -4 -CS001215000145 -19950329 -- -5 -CS020401000016 -19740915 +4400 - + +6 -CS015414000103 -19770809 ++++ +++In [62]:++++++ +# コード例2(np.where、betweenの活用) +df_tmp = df_customer[['customer_id', 'postal_cd']].copy() + +df_tmp['postal_flg'] = np.where(df_tmp['postal_cd'].str[0:3].astype(int) + .between(100, 209), 1, 0) + +pd.merge(df_tmp, df_receipt, how='inner', on='customer_id'). \ + groupby('postal_flg').agg({'customer_id':'nunique'}) ++ + ++ ++ + +Out[62]:+ + + +++ ++ +
@@ -22351,18 +23866,26 @@+ + customer_id - + +7 -CS029403000008 -19730817 +postal_flg +- 8 -CS015804000004 -19310502 +0 +3906 - 9 -CS033513000180 -19620711 +1 +4400 演習問題
-P-046: 顧客データフレーム(df_customer)の申し込み日(application_date)はYYYYMMDD形式の文字列型でデータを保有している。これを日付型に変換し、顧客ID(customer_id)とともに抽出せよ。データは10件を抽出すれば良い。
+P-054: 顧客データ(df_customer)の住所(address)は、埼玉県、千葉県、東京都、神奈川県のいずれかとなっている。都道府県毎にコード値を作成し、顧客ID、住所とともに10件表示せよ。値は埼玉県を11、千葉県を12、東京都を13、神奈川県を14とすること。
-In [52]:+In [63]:--@@ -22378,7 +23901,7 @@pd.concat([df_customer['customer_id'], - pd.to_datetime(df_customer['application_date'])], axis=1).head(10) +# コード例1(固定で切り出す) +df_customer_tmp = df_customer[['customer_id', 'address']].copy() + +df_customer_tmp['prefecture_cd'] = \ + df_customer['address'].str[0:3].map({'埼玉県': '11', + '千葉県':'12', + '東京都':'13', + '神奈川':'14'}) + +df_customer_tmp.head(10)演習問題 -
Out[52]:+Out[63]:@@ -22402,59 +23925,70 @@演習問題
customer_id -application_date +address +prefecture_cd 0 CS021313000114 -2015-09-05 +神奈川県伊勢原市粟窪********** +14 1 CS037613000071 -2015-04-14 +東京都江東区南砂********** +13 2 CS031415000172 -2015-05-29 +東京都渋谷区代々木********** +13 3 CS028811000001 -2016-01-15 +神奈川県横浜市泉区和泉町********** +14 4 CS001215000145 -2017-06-05 +東京都大田区仲六郷********** +13 5 CS020401000016 -2015-02-25 +東京都板橋区若木********** +13 6 CS015414000103 -2015-07-22 +東京都江東区北砂********** +13 7 CS029403000008 -2015-05-15 +千葉県浦安市海楽********** +12 8 CS015804000004 -2015-06-07 +東京都江東区北砂********** +13 @@ -22467,23 +24001,23 @@ 9 CS033513000180 -2015-07-28 +神奈川県横浜市旭区善部町********** +14 演習問題 -
--
-- -P-047: レシート明細データフレーム(df_receipt)の売上日(sales_ymd)はYYYYMMDD形式の数値型でデータを保有している。これを日付型に変換し、レシート番号(receipt_no)、レシートサブ番号(receipt_sub_no)とともに抽出せよ。データは10件を抽出すれば良い。
--In [53]:+In [64]:-@@ -22499,7 +24033,7 @@pd.concat([df_receipt[['receipt_no', 'receipt_sub_no']], - pd.to_datetime(df_receipt['sales_ymd'].astype('str'))], - axis=1).head(10) +# コード例2(正規表現を使う) +df_customer_tmp = df_customer[['customer_id', 'address']].copy() + +df_customer_tmp['prefecture_cd'] = \ + df_customer['address'].str.extract(r'(^.*?[都道府県])')[0].\ + map({'埼玉県': '11', + '千葉県':'12', + '東京都':'13', + '神奈川県':'14'}) + +df_customer_tmp.head(10)演習問題 -
Out[53]:+Out[64]:@@ -22522,71 +24056,71 @@演習問題
- receipt_no -receipt_sub_no -sales_ymd +customer_id +address +prefecture_cd 0 -112 -1 -2018-11-03 +CS021313000114 +神奈川県伊勢原市粟窪********** +14 1 -1132 -2 -2018-11-18 +CS037613000071 +東京都江東区南砂********** +13 2 -1102 -1 -2017-07-12 +CS031415000172 +東京都渋谷区代々木********** +13 3 -1132 -1 -2019-02-05 +CS028811000001 +神奈川県横浜市泉区和泉町********** +14 4 -1102 -2 -2018-08-21 +CS001215000145 +東京都大田区仲六郷********** +13 5 -1112 -1 -2019-06-05 +CS020401000016 +東京都板橋区若木********** +13 6 -1102 -2 -2018-12-05 +CS015414000103 +東京都江東区北砂********** +13 7 -1102 -1 -2019-09-22 +CS029403000008 +千葉県浦安市海楽********** +12 8 -1112 -2 -2017-05-04 +CS015804000004 +東京都江東区北砂********** +13 @@ -22603,19 +24137,43 @@ 9 -1102 -1 -2019-10-10 +CS033513000180 +神奈川県横浜市旭区善部町********** +14 演習問題
-P-048: レシート明細データフレーム(df_receipt)の売上エポック秒(sales_epoch)は数値型のUNIX秒でデータを保有している。これを日付型に変換し、レシート番号(receipt_no)、レシートサブ番号(receipt_sub_no)とともに抽出せよ。データは10件を抽出すれば良い。
+P-055: レシート明細(df_receipt)データの売上金額(amount)を顧客ID(customer_id)ごとに合計し、その合計金額の四分位点を求めよ。その上で、顧客ごとの売上金額合計に対して以下の基準でカテゴリ値を作成し、顧客ID、売上金額合計とともに10件表示せよ。カテゴリ値は順に1〜4とする。
++