最終更新日:2021/9/7
ここではビン分割について説明します。
例えば、あるクラスのテストの点数があった場合、10点ずつ区間を区切り、どの区間に何人含まれるか、など全体像を把握するのに役立ちます。
【説明すること】
- 1. ビン分割する
- 1.1. n分割してどこに属するかを知る :
pd.cut(df['clm'], n)
- 1.2. 分割する範囲を指定する :
pd.cut(df['clm'], bins=[0,50,100])
- 1.3. 分割の結果を(a,b]でなく、0,1,2…としたい :
pd.cut(df['clm'],bins=[0,50,100], labels=False))
- 1.4. 分割の結果に独自の値を付けたい :
pd.cut(df['clm'], bins=[0,50,100], labels=['Low', 'High'])
- 1.1. n分割してどこに属するかを知る :
- 2. ビン分割した範囲に含むデータの数を数える:
pd.cut().value_counts()
- 参考ページ
1. ビン分割する
pd.cut()
でビン分割ができます。オプションが幾つかあるので、以下で説明します。
1.1. n分割してどこに属するかを知る
pd.cut()
を使って、分割する数nを与え、
pd.cut(df['clm'], n)
と書きます。データの最大値と最小値を使って、自動でn分割します。但し、これは、各データがどの区間に属するかを示すだけになります。
【ポイント】
- dfを分割の対象にする場合、カラム名を指定します。(例:df[‘clm’])
- arrayも指定できます。
以下のcsvファイルを読み込んで例を示します。
もし結果をcsvに出力したい場合は、以下のようにdfに結果を入れれば、可能です。
1.2. 分割する範囲を指定する
分割する範囲を自分で指定する場合です。オプションのbins=
に範囲を指定します。
例えば、0から100まで20刻みの場合[0, 20, 40, 60, 80, 100]として、
pd.cut(df['clm'], bins=[0, 20, 40, 60, 80, 100])
と書きます。
【ポイント】
(1) 一番小さい値の扱い
範囲には注意が必要です。何も指定しないと、分割は
0<x<=20, 20<x<=40,…, 80<x<=100
となります。右側(20, 40, …, 100)を含むになります。 また、0は範囲に含まれません。
例えば、0がデータにあると、ビン分割の結果はNaNとなります。
但し、オプションでinclude_lowest=True
を指定すると、0<x<=20の区間だけは、0<=x<=20(0を含む)とできます。(正確には0の値を自動で少し小さくする)
(2) 等号はどちらに含むのか?
上のように、デフォルトの分割は「a<x<=b」となり、左を含まず、右を含むとなります。(これを大学の数学では(a,b]と書きます。)
オプションで、right = False
を指定すると、「a<=x<b」となり、左を含み、右を含まず、となります。
1.3. 分割の結果を(a,b]でなく、0,1,2…としたい
分割の結果を0, 1, 2,…と表示したい場合は、オプションでlabels=False
を指定します。番号は0始まりです。
1.4. 分割の結果に独自の値を付けたい
分割の結果を(a,b]でも0, 1, 2,…でもなく、独自の値にしたい場合です。
この場合、labels=
にlistを指定します。但し、分割の数と指定したlistの数が一致しなければいけません。
2. ビン分割した範囲に含むデータの数をかぞえる
ビン分割した結果を利用して、各範囲に含むデータの数をかぞえたい場合です。
pd.cut(df['clm'], bins=mybins, labels=mylables).value_counts()
または、 pd.value_counts(df_cut)
です。
ここで、後者のdf_cutはビン分割した結果です。例えば、df_cut = pd.cut(df['clm'], bins=mybins, labels=mylables)
が考えられます。
参考ページ
何度かご紹介していますが、以下のページがとても詳しいので、参考にしてください。
https://note.nkmk.me/python-pandas-cut-qcut-binning/