Python で解析 13
“Advent Calendar 2013 - Python で解析!” の十三日目。DataFrame - 8
1. データの準備
今回は cut を取り上げる。例えば、身長 10cm 刻みでの平均身長、平均体重を算出する…などで使うことができる。たぶん、 SQL にはない機能で、もし SQL で実現するなら case 式を使うだろう。
では、データの準備を。
In [1]: import pandas as pd In [2]: df = pd.DataFrame({ ...: 'height': [162, 178, 167, 171, 170], ...: 'weight': [51, 80, 55, 68, 71] ...: }) In [3]: df Out[3]: height weight 0 162 51 1 178 80 2 167 55 3 171 68 4 170 71
何はともあれ cut を使ってみると、こうなる。
In [4]: df.groupby(pd.cut(df.height, [160, 170, 180])).mean() Out[4]: height weight height (160, 170] 166.333333 59 (170, 180] 174.500000 74
何ができるか、なんとなく分かっただろうか?
2. cut とは
試しに cut のところだけを実行してみる。
In [5]: pd.cut(df.height, [160, 170, 180]) Out[5]: Categorical: height [(160, 170], (170, 180], (160, 170], (170, 180], (160, 170]] Levels (2): Index(['(160, 170]', '(170, 180]'], dtype=object)
ちょっと分かりにくいかもしれないが、こんな風に置き換わっている。
162 -> (160, 170] # 160 以上、170 未満 178 -> (170, 180] # 170 以上、180 未満 167 -> (160, 170] # 160 以上、170 未満 171 -> (170, 180] # 170 以上、180 未満 170 -> (170, 180] # 170 以上、180 未満
cut の二番目の引数に境界値を設定するだけで、データを分類してくれるので、とっても便利。ニュースで年代別だったり、所得区分別だったり…の統計値が取り上げられるが、そーゆー時に使える。
なお、デフォルトでは (以上, 未満] だが、[より大きい、以下) という指定もできる。
In [6]: pd.cut(df.height, [160, 170, 180], right=False) Out[6]: Categorical: height [[160, 170), [170, 180), [160, 170), [170, 180), [170, 180)] Levels (2): Index(['[160, 170)', '[170, 180)'], dtype=object)
3. qcut も
cut では、境界値を設定して分類したが、 qcut は分割数に応じて、実際のデータを分割する。
In [7]: pd.qcut(df.height, 2) Out[7]: Categorical: height [[162, 170], (170, 178], [162, 170], (170, 178], [162, 170]] Levels (2): Index(['[162, 170]', '(170, 178]'], dtype=object)
二つに分割されたことが Levels の方を見ると分かる。
In [8]: pd.qcut(df.height, 4) Out[8]: Categorical: height [[162, 167], (171, 178], [162, 167], (170, 171], (167, 170]] Levels (4): Index(['[162, 167]', '(167, 170]', '(170, 171]', '(171, 178]'], dtype=object)
四つに分割された。
「二十代の人の…」という時は cut で、「上位 25% の人の…」という時は qcut を使うという感じで、使い分ける。
今回はこんなところで。