Pandas データビニング(cut / qcut)

データビニング(バケット分割とも呼ばれます)は、連続変数を離散化するプロセスであり、データ前処理、特徴量エンジニアリング、データ分析でよく使用されます。


cut 等幅ビニング

cutデータを等幅の区間に分割します。

サンプル

import pandas as pd
import numpy as np

# 年齢データを作成
ages = pd.Series([5, 15, 25, 35, 45, 55, 65, 75, 85])

print("元データ:")
print(ages.tolist())
print()

# 等幅ビニング(5区間)
bins = [0, 20, 40, 60, 80, 100]
labels = ["子供", "若者", "中年", "中高年", "高齢者"]

age_bins = pd.cut(ages, bins=bins, labels=labels)
print("等幅ビニング結果:")
print(age_bins)
print()

# 右境界を含む
age_bins2 = pd.cut(ages, bins=4)
print("自動等幅ビニング:")
print(age_bins2)

カテゴリと境界を返す

サンプル

import pandas as pd
import numpy as np

ages = pd.Series([5, 15, 25, 35, 45])

# 区間インデックスを返す
result = pd.cut(ages, bins=4, labels=False)
print("区間インデックス:")
print(result)
print()

# 区間境界を返す
result = pd.cut(ages, bins=4, retbins=True)
print("区間境界:")
print(result[1])

qcut 等頻度ビニング

qcutデータをほぼ同じデータポイント数の区間に分割します。

サンプル

import pandas as pd
import numpy as np

# 不均一に分布したデータ
data = pd.Series([1, 1, 1, 2, 3, 4, 5, 10, 20, 30, 50, 100])

print("元データ:")
print(data.tolist())
print()

# 等幅ビニング(分布が不均一になる)
cut_result = pd.cut(data, q=4)
print("等幅ビニング:")
print(cut_result.value_counts())
print()

# 等頻度ビニング(各区間のデータポイント数がほぼ同じ)
qcut_result = pd.qcut(data, q=4)
print("等頻度ビニング:")
print(qcut_result.value_counts())

分位数を指定

サンプル

import pandas as pd

data = pd.Series(range(1, 101))

# 指定した分位数で分割
result = pd.qcut(data, q=[0, 0.1, 0.3, 0.7, 0.9, 1])
print("分位数による分割:")
print(result.value_counts().sort_index())

実践:データ分析

サンプル

import pandas as pd
import numpy as np

# 顧客の消費データをシミュレート
np.random.seed(42)
customers = pd.DataFrame({
    "顧客ID": range(1, 101),
    "消費金額": np.random.exponential(500, 100) + 100
})

# 異なる消費レベルにビニング
customers["消費レベル"] = pd.cut(
    customers["消費金額"],
    bins=[0, 300, 500, 800, float("inf")],
    labels=["低", "中", "高", "VIP"]
)

# 各レベルの顧客数を集計
print("消費レベル分布:")
print(customers["消費レベル"].value_counts())
print()

# レベルごとに平均消費を集計
print("各レベルの平均消費:")
print(customers.groupby("消費レベル")["消費金額"].mean().round(2))
その他の拡張