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

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


[100本ノックの記事](https://codezine.jp/article/detail/12456)
[100本ノックのガイド](https://github.com/The-Japan-DataScientist-Society/100knocks-preprocess/blob/master/docker/doc/100knocks_guide.pdf)

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

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

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

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

今回は２９～３２まで。
[[前回]](https://qiita.com/sola_wing529/items/97bfd1c09e68b5aa51bf)２３～２８
[[目次付き初回]](https://qiita.com/sola_wing529/items/5fdbd97308dd88da28eb)

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

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

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

[いつものサイト](https://note.nkmk.me/python-pandas-mode/)にヘルプして調べていてもなかなかうまくいかない。
なんでだ？と調べているとこんな[記事](https://teratail.com/questions/237404)が

>以下のサイトにも書かれていますが、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を表示せよ。

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

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

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

**分散**

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

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

![variance178.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/650016/19a085c3-b379-1b26-b0c9-1bd48cb9dae7.png)

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

```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番開始としています)(動作確認してません)

**プログラムならいける**

その後、[いろいろ](https://bellcurve.jp/statistics/course/5919.html)な[サイト](https://ai-trend.jp/basic-study/basic/variance/)や[動画](https://www.youtube.com/watch?v=lD35jzfrxaU)を見ているうちになんとなーく理解していきましたが大きく脱線したので切り上げてノックにもどります。

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

**[参考](http://sinhrks.hatenablog.com/entry/2014/11/27/232150)**

```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)
```
失敗例では
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/650016/163481fb-f344-b68b-e8b5-e038e9c708b9.png)
こんな感じの結果になったので、うまく結合できなかったのかと。単体でいいと思い、自分で回答できました。

いやー、時間かかった

#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`は[ここ](http://imaimamu.com/archives/1571)や[動画](https://www.youtube.com/watch?v=lD35jzfrxaU)から考えるに一致推定量か不偏推定量の違いかと。

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

**[参考](https://note.nkmk.me/python-pandas-quantile/)**

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

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

'''模範解答２'''
df_receipt.amount.quantile(q=np.arange(5)/4)
```
一応方向としては模範解答２に近いですが、np.arangeをつかうやり方はなるほどと思った。

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