【Pandasデータ前処理】cut()とqcut()で数値データを「ビン分割」!ビニング処理を徹底解説 📊
データ分析において、数値データ(例: 年齢、売上金額、テストの点数など)をそのまま扱うのではなく、特定の範囲で区切られたグループ(ビン、またはカテゴリ)に変換したい場合があります。例えば、年齢を「10代」「20代」「30代以上」といったグループに分けたり、売上金額を「低」「中」「高」といった階級に分類したりするような処理です。この数値データを区間に分割し、カテゴリデータに変換する作業を「ビニング処理」または「ビン分割」と呼びます。
Pandasは、このビニング処理を効率的に行うための強力な関数である**cut()とqcut()**を提供しています。この記事では、これら2つの関数の基本的な使い方から、それぞれの違い、そして知っておくと便利な応用例まで、短いサンプルコードと丁寧な解説を交えてご紹介します。
ビニング処理(ビン分割)とは?なぜ必要か?
ビニング処理は、連続する数値データを離散的なカテゴリデータに変換するデータ前処理手法です。
なぜビニング処理が必要なのでしょうか?
-
傾向の把握: 連続値をそのまま見てもわかりにくい傾向が、カテゴリに分けることで見えてくることがあります。
-
例: 年齢をグループ化することで、特定の年代の購買行動パターンが顕著になる。
-
-
外れ値の影響軽減: 極端に大きな値や小さな値(外れ値)が、分析結果に過度な影響を与えるのを緩和できます。
-
モデルの改善: 機械学習モデルによっては、連続値よりもカテゴリデータの方が性能が向上する場合があります。特に線形モデルなど。
-
データ可視化: グラフ(ヒストグラムなど)でデータを表示する際に、ビンの区切りを使うことでデータの分布がより明確になります。
cut()関数:指定した境界値でビン分割
cut()関数は、ユーザーが指定した固定の境界値(例: 0-10, 10-20, 20-30)に基づいて、数値データをビンに分割します。これは、あらかじめ決まった基準でデータを分類したい場合に適しています。
基本的な使い方:境界値の指定
bins引数に境界値のリストを渡します。
import pandas as pd
import numpy as np
# サンプルSeriesの作成 (年齢データ)
data = pd.Series([5, 12, 18, 25, 33, 40, 55, 62])
print("オリジナルデータ (年齢):\n", data)
# 年齢を'子供', '若者', '大人', '高齢者'に分割
# 境界値: 0-12歳, 12-25歳, 25-60歳, 60歳以上
bins = [0, 12, 25, 60, np.inf] # np.infは無限大
labels = ['子供', '若者', '大人', '高齢者']
age_categories = pd.cut(data, bins=bins, labels=labels, right=False)
print("\n`cut`で年齢をカテゴリ分割後:\n", age_categories)
解説:
-
bins=[0, 12, 25, 60, np.inf]: ビンの境界値をリストで指定します。np.infは正の無限大を表し、これ以降の全ての値をカバーします。 -
labels=['子供', '若者', '大人', '高齢者']: 各ビンに対応するラベルをリストで指定します。ラベルを指定しない場合、(境界値1, 境界値2]のような形式の区間が自動でラベルになります。 -
right=False: 各区間の**右側を閉じる(含まない)**ことを意味します。デフォルトはTrueで、右側が閉じます(例:(12, 25]は12より大きく25以下)。今回はright=Falseなので、[0, 12)は0以上12未満、[12, 25)は12以上25未満、となります。
ラベルを自動生成する
labels=Falseとすると、ビンが自動的に整数値(0, 1, 2…)で表されます。
# ラベルを自動生成 (0, 1, 2...)
age_bins_auto_label = pd.cut(data, bins=bins, labels=False, right=False)
print("\n`cut`で年齢を自動ラベル分割後:\n", age_bins_auto_label)
qcut()関数:データ数を均等に分割(四分位数など)
**qcut()**関数は、データ数をほぼ均等になるようにビン分割します。これは、データの分布に偏りがある場合でも、各ビンに同じくらいの数のデータポイントを入れたい場合に非常に有効です。四分位数(quartiles)や百分位数(percentiles)でデータを分割するのに似ています。
基本的な使い方:分割数の指定
q引数に分割したいビンの数を指定します。
# サンプルSeriesの作成 (売上データ)
sales_data = pd.Series([10, 25, 30, 45, 50, 65, 70, 85, 90, 100])
print("\nオリジナルデータ (売上):\n", sales_data)
# 売上データを4つのビンに均等分割 (四分位数)
# 各ビンには約25%のデータが入る
sales_quartiles = pd.qcut(sales_data, q=4, labels=['Q1', 'Q2', 'Q3', 'Q4'])
print("\n`qcut`で売上を四分位数分割後:\n", sales_quartiles)
解説:
-
q=4: データを4つのビンに分割することを指定します。この場合、それぞれのビンにはデータの約25%が含まれるように境界値が自動的に決定されます。 -
labels=['Q1', 'Q2', 'Q3', 'Q4']: 各ビンに対応するラベルを指定します。ラベルを指定しない場合、cut()と同様に自動で区間がラベルになります。
分位点を直接指定する
qにリストを渡すことで、特定の分位点(例: 0%, 25%, 50%, 75%, 100%)で分割できます。
# 中央値 (50パーセンタイル) で2分割
sales_median_split = pd.qcut(sales_data, q=[0, 0.5, 1], labels=['下位50%', '上位50%'])
print("\n`qcut`で中央値分割後:\n", sales_median_split)
解説:
q=[0, 0.5, 1]は、0パーセンタイル(最小値)、50パーセンタイル(中央値)、100パーセンタイル(最大値)でデータを分割することを意味します。
cut()とqcut()の使い分け
どちらの関数を使うべきかは、データの特性と分析の目的によって異なります。
-
cut():-
固定の基準や外部の基準(例: 法規制、教科の点数評価基準)でデータを区切りたい場合。
-
各ビンのデータ数が不均等になっても構わない場合。
-
例: 年齢層の定義、試験の評価段階(S, A, B, C)など。
-
-
qcut():-
各ビンにほぼ同数のデータポイントを含めたい場合。
-
データの分布に基づいた相対的なランク付けを行いたい場合。
-
例: 売上高を「上位25%」「次の25%」…のように分割、所得を「低所得」「中所得」「高所得」に均等に分類など。
-
まとめ
Pandasのcut()とqcut()関数は、数値データをカテゴリデータに変換するビニング処理のための強力なツールです。cut()はユーザーが指定した固定の境界値でデータを分割し、qcut()はデータ数をほぼ均等に分割します。
これらの関数を使いこなすことで、連続値データの傾向をより明確に把握したり、外れ値の影響を軽減したり、機械学習モデルの性能を向上させたりすることができます。データ分析の前処理において、cut()とqcut()を適切に使い分け、あなたのデータをより深く、より効果的に分析しましょう。




