0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

データサイエンス100本ノック(構造化データ加工編)をやってみた part3(P-023~P-031)

Last updated at Posted at 2021-08-03

 この記事はデータサイエンスを勉強しながら、データサイエンス協会が提供する__データサイエンス100本ノック(構造化データ加工編)__を解く過程を自分用にまとめたものです。

 チャプター   リンク   チャプター   リンク 
 P-001~P-016   part1   P-052~P-062   part6 
 P-017~P-022   part2   P-063~P-068   part7 
 P-023~P-031   part3   P-069~P-078   part8 
 P-032~P-039   part4   P-079~P-088   part9 
 P-040~P-051   part5  P-089~P-100  part10 
  • groupby()
  • agg()
  • 最大値 max()
  • 最小値 min()
  • 平均値 mean()
  • 中央値 median()
  • 最頻値 mode()
  • apply()
  • 分散 var()
  • 標準偏差 std()

P-023 groupby(), agg()

P-023: レシート明細データフレーム(df_receipt)に対し、店舗コード(store_cd)ごとに売上金額(amount)と売上数量(quantity)を合計せよ。

p023.py
df_receipt.groupby('store_cd').agg({'amount':'sum', 'quantity':'sum'}).reset_index()

 groupby('列名'):引数に列名を指定するとその列の値ごとにグルーピングされる。
 返されるのはGroupByオブジェクトでそれ自体をprint()で出力しても中身は表示されない。
 グルーピングしたオブジェクトの処理に関しては以下のページを参照。

P-024 max()

P-024: レシート明細データフレーム(df_receipt)に対し、顧客ID(customer_id)ごとに最も新しい売上日(sales_ymd)を求め、10件表示せよ。

p024.py
df_receipt.groupby('customer_id').sales_ymd.max().reset_index().head(10)

P-025 min()

P-025: レシート明細データフレーム(df_receipt)に対し、顧客ID(customer_id)ごとに最も古い売上日(sales_ymd)を求め、10件表示せよ。

p025.py
df_receipt.groupby('customer_id').sales_ymd.min().reset_index().head(10)

P-026

P-026: レシート明細データフレーム(df_receipt)に対し、顧客ID(customer_id)ごとに最も新しい売上日(sales_ymd)と古い売上日を求め、両者が異なるデータを10件表示せよ。

myp026.py
df_max = df_receipt.groupby('customer_id').sales_ymd.max().reset_index()
df_min = df_receipt.groupby('customer_id').sales_ymd.min().reset_index()
df_max_min = pd.concat([df_max, df_min['sales_ymd']], axis=1)
df_max_min.columns = ['customer_id', 'sales_ymd_max', 'sales_ymd_min']
df_max_min.query('sales_ymd_max != sales_ymd_min').head(10)

 最も新しい売り上げ日(df_max)と最も古い売り上げ日(df_min)のデータフレームを作り、それを横方向に結合したdf_max_minを作成。
 その後、カラム名を変更し、条件に合うものを出力した。

p026.py
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.columns = ['customer_id', 'sales_ymd_max', 'sales_ymd_min'] でも可
df_tmp.query('sales_ymd_max != sales_ymd_min').head(10)

 解答ではagg()メソッドを使って上のように書いている。
 2行目でリスト内包表記を使いカラム名を変更している。

P-027 mean()

P-027: レシート明細データフレーム(df_receipt)に対し、店舗コード(store_cd)ごとに売上金額(amount)の平均を計算し、降順でTOP5を表示せよ。

p027.py
df_receipt.groupby('store_cd').amount.mean().reset_index().sort_values('amount', ascending=False).head(5)

 agg()メソッドを使うなら

p027.py
df_receipt.groupby('store_cd').agg({'amount':'mean'}).reset_index().sort_values('amount', ascending=False).head(5)

P-028 median()

P-028: レシート明細データフレーム(df_receipt)に対し、店舗コード(store_cd)ごとに売上金額(amount)の中央値を計算し、降順でTOP5を表示せよ。

p028.py
df_receipt.groupby('store_cd').amount.median().reset_index().sort_values('amount', ascending=False).head(5)

 これもP-027と同様にamount.median()agg({'amount':'median'})と書いても同様の結果を得られる。

P-029 mode(), apply()

P-029: レシート明細データフレーム(df_receipt)に対し、店舗コード(store_cd)ごとに商品コード(product_cd)の最頻値を求めよ。

p029.py
df_receipt.groupby('store_cd').product_cd.apply(lambda x: x.mode()).reset_index()

 GroupByオブジェクトの最頻値は他の関数sum,mean,median等と違い、そのまま使うことができない。
 apply()やvalue_counts()を組み合わせる必要がある。

 apply():引数に一次元配列に適用可能な関数を渡す。
 デフォルトで各列、axis=1で各行に適用される。
 解答では無名関数( lambda )を使っている。

P-030 var()

P-030: レシート明細データフレーム(df_receipt)に対し、店舗コード(store_cd)ごとに売上金額(amount)の標本分散を計算し、降順でTOP5を表示せよ。

p030.py
df_receipt.groupby('store_cd').amount.var(ddof=0).reset_index().sort_values('amount', ascending=False).head(5)

 分散の式
$$ s^2 = \frac{1}{n} \sum_{i=1}^{n} (x_i - \bar{x})^2 $$

 解答にも書いてあるんですがNumpyとPandasでは分散var()と標準偏差std()のデフォルト値が変わってきます。
 これはNumpyはデフォルト値で標本分散が求まり、Pandasでは不偏分散の値が求まるようになっているからだそうです。

 var()で分散を計算する際、平均との偏差の2乗の和をn - ddofで割ります。
 Pandasではデフォルトがddof=1であるため、引数にddof=0を渡します。

P-031 std()

P-031: レシート明細データフレーム(df_receipt)に対し、店舗コード(store_cd)ごとに売上金額(amount)の標本標準偏差を計算し、降順でTOP5を表示せよ。

p031.py
df_receipt.groupby('store_cd').amount.std(ddof=0).reset_index().sort_values('amount', ascending=False).head(5)

 P-030と同じようにstd()の引数にddof=0を渡します。

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?