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