Pandas pd.cut() 関数
pd.cut()は Pandas ライブラリで使用される連続データをビニング(Binning)するための関数です。数値データを指定した区間に従って離散的なカテゴリに分割し、データ分析におけるグループ集計や可視化に非常に適しています。
ビニング操作はデータ分析で非常に一般的です。例えば、年齢を「青少年」「中年」「高齢者」に分類したり、成績を「不合格」「合格」「良好」「優秀」などに分類したりします。
単語の意味: cut「カット」という意味で、ここでは連続したデータ区間を複数の離散的な区間に「切り分ける」ことを指します。
基本構文とパラメータ
pd.cut()は Pandas ライブラリのトップレベル関数で、連続変数を離散化するために使用されます。
構文形式
pd.cut(x, bins, right=True, labels=None, retbins=False, precision=3, include_lowest=False)
パラメータの説明
- パラメータ:
x- 型: リスト、Series、配列などの配列風オブジェクト。
- 説明: ビニングを行う連続数値データ。
- パラメータ:
bins- 型: 整数、スカラー(区間境界)、または IntervalIndex。
- 説明: ビニングの方法。整数(等幅のビンにいくつ分割するかを指定)またはリスト(具体的な区間境界を指定)を指定できます。
- パラメータ:
right- 型: ブール値。
- 説明> 右閉区間を使用するかどうか。デフォルトは
True(つまり [a, b] 形式)。もしFalseに設定すると、左閉右開区間 (a, b] になります。
- パラメータ:
labels- 型: 配列または None。
- 説明: 各区間にカスタムラベルを指定します。指定しない場合は、区間表記(例:「(0, 10]」)が使用されます。
- パラメータ:
retbins- 型> ブール値。
- 説明> もし
Trueの場合、戻り値にビンの境界値が含まれます。デフォルトはFalse。
- パラメータ:
include_lowest- 型> ブール値。
- 説明> もし
Trueの場合、最初の区間に左境界が含まれます。デフォルトはFalse。
関数の説明
- 戻り値: Categorical 型の Series を返します。各値はその属する区間に対応します。
- 効果: 連続する数値を離散的なカテゴリ(区間)にマッピングします。
実例
簡単なものから複雑なものまで一連の例を通して、pd.cut()の使い方を完全にマスターしましょう。
例1:基本用法 - 等幅ビニング
実例
import pandas as pd
import numpy as np
# 1. 数値データを作成
scores = pd.Series([55, 70, 82, 45, 90, 65, 78, 88, 92, 58])
print("=== 元のスコア ===")
print(scores)
# 2. スコアを3つの等幅の区間に分割
result = pd.cut(scores, bins=3)
print("\n=== pd.cut(scores, bins=3) 等幅ビニング ===")
print(result)
# 3. ビンの境界値を確認
result_bins = pd.cut(scores, bins=3, retbins=True)
print("\n=== ビン境界の取得 ===")
print(f"ビン境界: {result_bins)
import numpy as np
# 1. 数値データを作成
scores = pd.Series([55, 70, 82, 45, 90, 65, 78, 88, 92, 58])
print("=== 元のスコア ===")
print(scores)
# 2. スコアを3つの等幅の区間に分割
result = pd.cut(scores, bins=3)
print("\n=== pd.cut(scores, bins=3) 等幅ビニング ===")
print(result)
# 3. ビンの境界値を確認
result_bins = pd.cut(scores, bins=3, retbins=True)
print("\n=== ビン境界の取得 ===")
print(f"ビン境界: {result_bins)
実行結果の予想:
=== 原始分数 === 0 55 1 70 2 82 3 45 4 90 5 65 6 78 7 88 8 92 9 58 === pd.cut(scores, bins=3) 等宽分箱 === 0 (44.667, 60.667] 1 (60.667, 76.333] 2 (76.333, 92.0] 3 (44.667, 60.667] 4 (76.333, 92.0] 5 (60.667, 76.333] 6 (60.667, 76.333] 7 (76.333, 92.0] 8 (76.333, 92.0] 9 (44.667, 60.667] dtype: category Categories (3, interval[float64]): [(44.667, 60.667] < (60.667, 76.333] < (76.333, 92.0] === 返回分箱边界 === 分箱边界: [44.667 60.667 76.333 92. ]
コードの解説:
bins=3データを自動的に3つの等幅の区間に分割することを示します。- Pandas はデータの最小値と最大値に基づいて区間境界を自動的に計算します。
- 返されるのは Categorical 型で、各値は Interval(区間)オブジェクトです。
- デフォルトでは右閉区間、つまり (a, b] 形式が使用されます。
例2:カスタム区間境界
実際のアプリケーションでは、ビジネス要件に応じてビニング境界をカスタマイズする必要がよくあります。
実例
import pandas as pd
import numpy as np
# 成績データを作成
scores = pd.Series([55, 70, 82, 45, 90, 65, 78, 88, 92, 58, 73, 67, 81, 49, 95])
# カスタムビニング境界:不合格、合格、良好、優秀
bins = [0, 60, 75, 90, 100]
labels = ['不合格', '合格', '良好', '優秀']
result = pd.cut(scores, bins=bins, labels=labels, include_lowest=True)
print("=== 元の成績 ===")
print(scores.values)
print("\n=== ビニング結果 ===")
print(result)
# 各ランクの人数を集計
print("\n=== 成績分布の集計 ===")
print(result.value_counts().sort_index())
import numpy as np
# 成績データを作成
scores = pd.Series([55, 70, 82, 45, 90, 65, 78, 88, 92, 58, 73, 67, 81, 49, 95])
# カスタムビニング境界:不合格、合格、良好、優秀
bins = [0, 60, 75, 90, 100]
labels = ['不合格', '合格', '良好', '優秀']
result = pd.cut(scores, bins=bins, labels=labels, include_lowest=True)
print("=== 元の成績 ===")
print(scores.values)
print("\n=== ビニング結果 ===")
print(result)
# 各ランクの人数を集計
print("\n=== 成績分布の集計 ===")
print(result.value_counts().sort_index())
実行結果の予想:
=== 原始成绩 [55 70 82 45 90 65 78 88 92 58 73 67 81 49 95] === 分箱结果 0 及格 1 良好 2 良好 3 不及格 4 优秀 ... 12 良好 13 不及格 14 优秀 dtype: category Categories (4, interval[int64]): [不及格 < 及格 < 良好 < 优秀] === 成绩分布统计 不及格 3 及格 4 良好 5 优秀 3 dtype: int64
コードの解説:
bins=[0, 60, 75, 90, 100]4つの区間を定義:[0-60], (60-75], (75-90], (90-100]labelsパラメータで各区間に分かりやすい中国語ラベルを指定include_lowest=True最初の区間に左境界0が含まれるようにするvalue_counts()各ランクの人数を簡単に集計できる
例3:右閉区間/左閉区間の使用
実例
import pandas as pd
import numpy as np
# テストデータ
data = pd.Series([10, 20, 30, 40, 50])
# デフォルトの右閉区間 [a, b]
result1 = pd.cut(data, bins=4)
print("=== デフォルトの右閉区間 [a, b] ===")
print(result1)
# 左閉右開区間 (a, b]
result2 = pd.cut(data, bins=4, right=False)
print("\n=== 左閉右開区間 (a, b] ===")
print(result2)
import numpy as np
# テストデータ
data = pd.Series([10, 20, 30, 40, 50])
# デフォルトの右閉区間 [a, b]
result1 = pd.cut(data, bins=4)
print("=== デフォルトの右閉区間 [a, b] ===")
print(result1)
# 左閉右開区間 (a, b]
result2 = pd.cut(data, bins=4, right=False)
print("\n=== 左閉右開区間 (a, b] ===")
print(result2)
実行結果の予想:
=== 默认右闭区间 [a, b] 0 (7.5, 17.5] 1 (17.5, 27.5] 2 (27.5, 37.5] 3 (37.5, 47.5] 4 (47.5, 57.5] dtype: category === 左闭右开区间 (a, b] 0 [10, 17.5) 1 [17.5, 27.5) 2 [27.5, 37.5) 3 [37.5, 47.5) 4 [47.5, 57.5) dtype: category
コードの解説:
- デフォルトでは右閉区間を使用
[a, b]、つまり右境界を含む - 設定
right=Falseを左閉右開区間に変更[a, b) - 区間の開閉方式は境界値の分類に影響します
注意事項
重要な注意:
- データに
bins指定された範囲を超える値がある場合、NaNbinsの境界は単調増加である必要があります- カスタムラベルを使用する場合、ラベルの数は境界の数より1つ少なくする必要があります
- ビニング後の結果は Categorical 型で、文字列メソッドを使用して処理できます
その他の拡張
Pandas よく使う関数