Pythonでデータ分析する時、例えば年齢のデータがずらーっとあって、
『それぞれ何人いるの?』
と、全体の傾向を掴むため、度数分布表を作ってヒストグラムを作る。
今回はPythonでデータを小分けにする方法を書きます。
ラベルのある『ビンに詰める、ビンに分ける』という事で『ビニング』と言うそうです。
もっと深く調べたい方は『Python ビニング』で検索すると良いと思います。
例えばこんなデータ
import numpy as np
import pandas as pd
ages = [20, 22, 25, 27, 21, 23, 37, 31, 61, 45, 41, 32]
Pandasのcutオブジェクトを利用
# 18歳~25歳、26歳~35歳、36歳~60歳、61歳以上の4つの分に分割する
bins = [18, 25, 35, 60, 100]
cats = pd.cut(ages, bins)
cats
# [(18, 25], (18, 25], (18, 25], (25, 35], (18, 25], ..., (25, 35], (60, 100], (35, 60], (35, 60], (25, 35]]
# Length: 12
# Categories (4, interval[int64]): [(18, 25] < (25, 35] < (35, 60] < (60, 100]]
# Categoriesオブジェクトが生成される
cats.codes
# array([0, 0, 0, 1, 0, 0, 2, 1, 3, 2, 2, 1], dtype=int8)
cats.categories
# IntervalIndex([(18, 25], (25, 35], (35, 60], (60, 100]],
# closed='right',
# dtype='interval[int64]')
pd.value_counts(cats)
# (18, 25] 5
# (35, 60] 3
# (25, 35] 3
# (60, 100] 1
# dtype: int64
# (は開区間→境界を含まない
# [は閉区間→境界を含む
# という意味
左側を閉区間にする場合
# right=Falseを引数として渡すと左側を閉区間にすることが可能
pd.cut(ages, [18, 26, 36, 61, 100], right=False)
# [[18, 26), [18, 26), [18, 26), [26, 36), [18, 26), ..., [26, 36), [61, 100), [36, 61), [36, 61), [26, 36)]
# Length: 12
# Categories (4, interval[int64]): [[18, 26) < [26, 36) < [36, 61) < [61, 100)]
labelsオプションを設定するとビンの名前を設定できる
group_names = ['Youth', 'youngAdult', 'Middleagged', 'Senior']
pd.cut(ages, bins, labels=group_names)
# ['Youth', 'Youth', 'Youth', 'youngAdult', 'Youth', ..., 'youngAdult', 'Senior', 'Middleagged', 'Middleagged', 'youngAdult']
# Length: 12
# Categories (4, object): ['Youth' < 'youngAdult' < 'Middleagged' < 'Senior']
データの最小値と最大値を基にして、等間隔で区切る場合
# 例えばこんなデータ
data = np.random.rand(20)
print(data)
# [0.66214426 0.90929141 0.06582663 0.491324 0.36464093 0.13885098
# 0.92869376 0.72465602 0.3951001 0.19924998 0.70869471 0.57450103
# 0.73736431 0.19260634 0.75599347 0.43365036 0.66550748 0.63392544
# 0.12680674 0.25738036]
pd.cut(data, 4, precision=2)
# precisionは境界値を小数点以下2桁の精度に設定するためのもの
# [(0.5, 0.71], (0.71, 0.93], (0.065, 0.28], (0.28, 0.5], (0.28, 0.5], ..., (0.28, 0.5], (0.5, 0.71], (0.5, 0.71], (0.065, 0.28], (0.065, 0.28]]
# Length: 20
# Categories (4, interval[float64]): [(0.065, 0.28] < (0.28, 0.5] < (0.5, 0.71] < (0.71, 0.93]]
qcut サンプルの分位点を基準にビンを設定する
# qcut サンプルの分位点を基準にビンを設定する
data = np.random.randn(1000) # 正規分布のデータ
cats = pd.qcut(data, 4) # 4つの四分位範囲のビンに分割
cats
# [(-0.654, -0.0428], (0.657, 3.281], (-0.654, -0.0428], (-0.654, -0.0428], (-0.654, -0.0428], ..., (-2.715, -0.654], (-0.0428, 0.657], (-2.715, -0.654], (-2.715, -0.654], (-0.0428, 0.657]]
# Length: 1000
# Categories (4, interval[float64]): [(-2.715, -0.654] < (-0.654, -0.0428] < (-0.0428, 0.657] <
(0.657, 3.281]]
pd.value_counts(cats)
# (0.657, 3.281] 250
# (-0.0428, 0.657] 250
# (-0.654, -0.0428] 250
# (-2.715, -0.654] 250
# dtype: int64
任意の分位点をビンの境界とする方法
cats = pd.qcut(data, [0, 0.1, 0.5, 0.9, 1.])
cats
# [(-1.196, -0.0428], (-0.0428, 1.291], (-1.196, -0.0428], (-1.196, -0.0428], (-1.196, -0.0428], ..., (-2.715, -1.196], (-0.0428, 1.291], (-1.196, -0.0428], (-2.715, -1.196], (-0.0428, 1.291]]
# Length: 1000
# Categories (4, interval[float64]): [(-2.715, -1.196] < (-1.196, -0.0428] < (-0.0428, 1.291] <
(1.291, 3.281]]
pd.value_counts(cats)
# (-0.0428, 1.291] 400
# (-1.196, -0.0428] 400
# (1.291, 3.281] 100
# (-2.715, -1.196] 100
# dtype: int64
![]() |
![]() |
---|
コメント