データサイエンス 100 本ノックとは

The-Japan-DataScientist-Society/100knocks-preprocess: データサイエンス 100 本ノック(構造化データ加工編)

Google Colab で データサイエンス 100 本ノックをするにあたって

以下の ipynb ファイルを使用させていただきました。

noguhiro2002/100knocks-preprocess_ForColab-AzureNotebook: データサイエンス 100 本ノック(構造化データ加工編)For Azure_Notebook/Google_Colabo

実行ファイル

データサイエンス 100 本ノック by tomowarkar

001

P-001: レシート明細のデータフレーム(df_receipt)から全項目の先頭 10 件を表示し、どのようなデータを保有しているか目視で確認せよ。

df_receipt.head(10)
   sales_ymd  sales_epoch store_cd  ...  product_cd  quantity amount
0   20181103   1257206400   S14006  ...  P070305012         1    158
1   20181118   1258502400   S13008  ...  P070701017         1     81
2   20170712   1215820800   S14028  ...  P060101005         1    170
3   20190205   1265328000   S14042  ...  P050301001         1     25
4   20180821   1250812800   S14025  ...  P060102007         1     90
5   20190605   1275696000   S13003  ...  P050102002         1    138
6   20181205   1259971200   S14024  ...  P080101005         1     30
7   20190922   1285113600   S14040  ...  P070501004         1    128
8   20170504   1209859200   S13020  ...  P071302010         1    770
9   20191010   1286668800   S14027  ...  P071101003         1    680

[10 rows x 9 columns]

002

P-002: レシート明細のデータフレーム(df_receipt)から売上日(sales_ymd)、顧客 ID(customer_id)、商品コード(product_cd)、売上金額(amount)の順に列を指定し、10 件表示させよ。

df_receipt[["sales_ymd", "customer_id", "product_cd", "amount"]].head(10)
   sales_ymd     customer_id  product_cd  amount
0   20181103  CS006214000001  P070305012     158
1   20181118  CS008415000097  P070701017      81
2   20170712  CS028414000014  P060101005     170
3   20190205  ZZ000000000000  P050301001      25
4   20180821  CS025415000050  P060102007      90
5   20190605  CS003515000195  P050102002     138
6   20181205  CS024514000042  P080101005      30
7   20190922  CS040415000178  P070501004     128
8   20170504  ZZ000000000000  P071302010     770
9   20191010  CS027514000015  P071101003     680

003

P-003: レシート明細のデータフレーム(df_receipt)から売上日(sales_ymd)、顧客 ID(customer_id)、商品コード(product_cd)、売上金額(amount)の順に列を指定し、10 件表示させよ。ただし、sales_ymd は sales_date に項目名を変更しながら抽出すること。

df_receipt[["sales_ymd", "customer_id", "product_cd", "amount"]]\
  .rename(columns={"sales_ymd": "sales_date"}).head(10)
   sales_date     customer_id  product_cd  amount
0    20181103  CS006214000001  P070305012     158
1    20181118  CS008415000097  P070701017      81
2    20170712  CS028414000014  P060101005     170
3    20190205  ZZ000000000000  P050301001      25
4    20180821  CS025415000050  P060102007      90
5    20190605  CS003515000195  P050102002     138
6    20181205  CS024514000042  P080101005      30
7    20190922  CS040415000178  P070501004     128
8    20170504  ZZ000000000000  P071302010     770
9    20191010  CS027514000015  P071101003     680

004

P-004: レシート明細のデータフレーム(df_receipt)から売上日(sales_ymd)、顧客 ID(customer_id)、商品コード(product_cd)、売上金額(amount)の順に列を指定し、以下の条件を満たすデータを抽出せよ。

  • 顧客 ID(customer_id)が"CS018205000001”
df_receipt[["sales_ymd", "customer_id", "product_cd", "amount"]]\
  .query("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

別解

複数検索を想定するならこうですね

df_receipt[["sales_ymd", "customer_id", "product_cd", "amount"]]\
  .query("customer_id in ['CS018205000001']")
df_receipt[["sales_ymd", "customer_id", "product_cd", "amount"]]\
  [df_receipt.customer_id.isin(["CS018205000001"])]

005

P-005: レシート明細のデータフレーム(df_receipt)から売上日(sales_ymd)、顧客 ID(customer_id)、商品コード(product_cd)、売上金額(amount)の順に列を指定し、以下の条件を満たすデータを抽出せよ。

  • 顧客 ID(customer_id)が"CS018205000001”
  • 売上金額(amount)が 1,000 以上
df_receipt[["sales_ymd", "customer_id", "product_cd", "amount"]]\
  .query("customer_id == 'CS018205000001' & amount >= 1000")
       sales_ymd     customer_id  product_cd  amount
36      20180911  CS018205000001  P071401012    2200
68117   20190226  CS018205000001  P071401020    2200
72254   20180911  CS018205000001  P071401005    1100

別解

pandas.DataFrameでのqueryを使わない複数指定の場合は 条件毎にカッコで括って、& で繋ぐ必要があり、慣れないとすんなり書けないですね。

df_receipt[["sales_ymd", "customer_id", "product_cd", "amount"]]\
  [(df_receipt.customer_id == "CS018205000001") & (df_receipt.amount >= 1000)]

006

P-006: レシート明細データフレーム「df_receipt」から売上日(sales_ymd)、顧客 ID(customer_id)、商品コード(product_cd)、売上数量(quantity)、売上金額(amount)の順に列を指定し、以下の条件を満たすデータを抽出せよ。

  • 顧客 ID(customer_id)が"CS018205000001”
  • 売上金額(amount)が 1,000 以上または売上数量(quantity)が 5 以上
df_receipt[["sales_ymd", "customer_id", "product_cd", "quantity", "amount"]]\
  .query("customer_id == 'CS018205000001' & (amount >= 1000 | quantity>= 5)")
       sales_ymd     customer_id  product_cd  quantity  amount
36      20180911  CS018205000001  P071401012         1    2200
9843    20180414  CS018205000001  P060104007         6     600
21110   20170614  CS018205000001  P050206001         5     990
68117   20190226  CS018205000001  P071401020         1    2200
72254   20180911  CS018205000001  P071401005         1    1100

007

P-007: レシート明細のデータフレーム(df_receipt)から売上日(sales_ymd)、顧客 ID(customer_id)、商品コード(product_cd)、売上金額(amount)の順に列を指定し、以下の条件を満たすデータを抽出せよ。

  • 顧客 ID(customer_id)が"CS018205000001”
  • 売上金額(amount)が 1,000 以上 2,000 以下
df_receipt[["sales_ymd", "customer_id", "product_cd", "amount"]]\
  .query("customer_id == 'CS018205000001' & 2000 >= amount >= 1000")
       sales_ymd     customer_id  product_cd  amount
72254   20180911  CS018205000001  P071401005    1100

008

P-008: レシート明細のデータフレーム(df_receipt)から売上日(sales_ymd)、顧客 ID(customer_id)、商品コード(product_cd)、売上金額(amount)の順に列を指定し、以下の条件を満たすデータを抽出せよ。

  • 顧客 ID(customer_id)が"CS018205000001”
  • 商品コード(product_cd)が"P071401019"以外
df_receipt[["sales_ymd", "customer_id", "product_cd", "amount"]]\
  .query("customer_id == 'CS018205000001' & product_cd != 'P071401019'")
       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

009

P-009: 以下の処理において、出力結果を変えずに OR を AND に書き換えよ。

df_store.query('not(prefecture_cd == "13" | floor_area > 900)')

ド・モルガンの法則を使う問題ですね

df_store.query('prefecture_cd != "13" & floor_area <= 900')
   store_cd store_name  prefecture_cd  ... longitude  latitude floor_area
18   S14046       北山田店             14  ...  139.5916  35.56189      831.0
20   S14011      日吉本町店             14  ...  139.6316  35.54655      890.0
38   S12013       習志野店             12  ...  140.0220  35.66122      808.0

010

P-010: 店舗データフレーム(df_store)から、店舗コード(store_cd)が"S14"で始まるものだけ全項目抽出し、10 件だけ表示せよ。

df_store[df_store.store_cd.str.startswith("S14")].head(10)
   store_cd store_name  prefecture_cd  ... longitude  latitude floor_area
2    S14010        菊名店             14  ...  139.6326  35.50049     1732.0
3    S14033       阿久和店             14  ...  139.4961  35.45918     1495.0
4    S14036     相模原中央店             14  ...  139.3716  35.57327     1679.0
7    S14040       長津田店             14  ...  139.4994  35.52398     1548.0
9    S14050      阿久和西店             14  ...  139.4961  35.45918     1830.0
12   S14028       二ツ橋店             14  ...  139.4963  35.46304     1574.0
16   S14012      本牧和田店             14  ...  139.6582  35.42156     1341.0
18   S14046       北山田店             14  ...  139.5916  35.56189      831.0
19   S14022        逗子店             14  ...  139.5789  35.29642     1838.0
20   S14011      日吉本町店             14  ...  139.6316  35.54655      890.0

[10 rows x 10 columns]

別解

numexpr がインストールされている場合 pandas.DataFrame.query の引数 engine のデフォルト値が numexpr になるため、startswith を使いたい場合 engine='python' にてあげる必要があるみたい1です。

df_store.query('store_cd.str.startswith("S14")', engine='python').head(10)

  1. https://note.nkmk.me/python-pandas-query/ ↩︎