データサイエンス100本ノック~初心者未満の戦いpart5


これはデータサイエンティストの卵がわけもわからないまま100本ノックを行っていく奮闘録である。
完走できるか謎。途中で消えてもQiitaにあげてないだけと思ってください。

100本ノックの記事
100本ノックのガイド

ネタバレも含みますのでやろうとされている方は注意

ココでグダグダ書いているのはネタバレ防止に1ページ分くらいの尺を稼いでいるからです()

今回は脱線に脱線を重ね、自分が何を調べたいのかわからなくなりました(原因は30本目)

コレは見づらい!この書き方は危険!等ありましたら教えていただきたいです。心にダメージを負いながら糧とさせていただきます。

今回は29~32まで。
[前回]23~28
[目次付き初回]

今回は分からないこと多かったです

29本目

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

最頻値はモードというのは分かっていましたが、前回の続きで
groupby(store_cd).agg({'product_cd':['mode']})
と書くとコケます。というか、aggのなかには無いっぽい?

いつものサイトにヘルプして調べていてもなかなかうまくいかない。
なんでだ?と調べているとこんな記事

以下のサイトにも書かれていますが、groupbyした後にmodeで最頻値を求める場合は、value_countsやapplyを組み合わせる必要があります。英語ですが、コードの例はシンプルですぐに理解できると思いますので、参考にしてみてください。
https://github.com/pandas-dev/pandas/issues/11562
df.groupby('grouping_content').最頻を求めたい対象.apply(lambda x: x.mode())

ラムダェ……

mine29.py
df=df_receipt
df=df.groupby('store_cd').product_cd.apply(lambda x: x.mode()).reset_index()
df.head(5)

うん、わからん

30本目

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

問題文連投してる時点で察してください

まず、数学が高2で苦手になり10年以上経過した自分としてはシグマの上下左右につらつらと文字列や大きな記号が書いてあると死にかけます
そんな自分はExcelで標準偏差なんか求める時も基本コピペ

そんな中出てきた「標本分散」の文字

分散

なんか書いてあると白眼になるよね。ならない?

標準分散の公式はこんな感じ

死にかけた眼をコスりながらとりあえずプログラムっぽく書いて頭を整理します

ikinokoru.py
def Sno2jo(X_list):

   n = len(X_list)
   X_ave = sum(X_list) / n
   ret = 0.0

   for X in range(X_list):
      ret += (X - X_ave)**2

   ret = ret / n
   return ret

こんな感じか……?(配列は0番開始としています)(動作確認してません)

プログラムならいける

その後、いろいろサイト動画を見ているうちになんとなーく理解していきましたが大きく脱線したので切り上げてノックにもどります。

今回は統計関数を使えばきっと楽なのだろうと思い(そのためにPythonしてるわけだし)調べて解きます

参考

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

'''模範解答'''
df_receipt.groupby('store_cd').amount.var(ddof=0).reset_index().sort_values('amount', ascending=False).head(5)

'''失敗例'''
df=pd.concat([df['store_cd'],df.groupby('store_cd').amount.var(ddof=0)],axis=0)

失敗例では

こんな感じの結果になったので、うまく結合できなかったのかと。単体でいいと思い、自分で回答できました。

いやー、時間かかった

31本目

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

30のをそのままコピペで突破
ddof=FalseだとIntで渡せと言われて0にしました。
ddofここ動画から考えるに一致推定量か不偏推定量の違いかと。

32本目

パーセンタイル値の意味が分からなかった(なんとなくは分かったが)ので、調べてから参考サイトを調べる(流れるようなカンニング)

参考

mine32.py
df=df_receipt
df['amount'].quantile([0.0,0.25,0.5,0.75,1.0])

'''模範解答1'''
np.percentile(df_receipt['amount'], q=[25, 50, 75,100])

'''模範解答2'''
df_receipt.amount.quantile(q=np.arange(5)/4)

一応方向としては模範解答2に近いですが、np.arangeをつかうやり方はなるほどと思った。

今回はここまで

もし今回のCSVを使って遊んでみたい人用
保存先\100knocks-preprocess\docker\work
ここに各種CSVあります