现在位置: 首页 > Pandas 教程 > 正文

Pandas pd.qcut() 函数

Pandas 通用函数 Pandas 常用函数


pd.qcut() 是 Pandas 库中用于按分位数进行分箱的函数。它将数据划分为相等数量的样本,每个箱子包含大约相同数量的数据点。

pd.cut()(等宽分箱)不同,pd.qcut() 确保每个区间内的数据量相等,非常适合处理偏态分布的数据,或者需要按照数据的自然分位数来划分的情况。

单词释义qcut 中 "q" 代表 "quantile"(分位数),意思是按分位数来"切割"数据。


基本语法与参数

pd.qcut() 是 Pandas 库的顶级函数,用于基于分位数进行离散化。

语法格式

pd.qcut(x, q, labels=None, retbins=False, precision=3, duplicates='raise')

参数说明

  • 参数x
    • 类型: 数组-like 对象,如列表、Series、数组等。
    • 描述: 要进行分箱的连续数值数据。
  • 参数q
    • 类型: 整数或分位数数组。
    • 描述: 分箱的数量或具体的分位数。如果是一个整数 n,表示将数据分成 n 个等量的组(每个组约有 n/1 的数据)。也可以是一个分位数数组(如 [0, 0.25, 0.5, 0.75, 1.0])。
  • 参数labels
    • 类型: 数组或 None。
    • 描述: 为每个区间指定自定义标签。如果不指定,则使用分位数表示(如 "(0, 25]")。
  • 参数retbins
    • 类型: 布尔值。
    • 描述> 如果为 True,返回结果中包含分箱的边界值。默认为 False
  • 参数duplicates
    • 类型: 字符串('raise' 或 'drop')。
    • 描述> 如果分箱边界有重复(导致区间数量少于指定的 q 值),'raise' 会抛出异常,'drop' 会删除重复的边界。默认为 'raise'

函数说明

  • 返回值: 返回一个 Categorical 类型的 Series,每个值对应其所属的分位数组。
  • 效果: 将连续数值按分位数映射为离散的类别,每个类别包含约相同数量的样本。

实例

让我们通过一系列从简单到复杂的例子,彻底掌握 pd.qcut() 的用法。

示例 1:基础用法 - 按四分位数分箱( quartile)

实例

import pandas as pd
import numpy as np

# 1. 创建有偏斜的数值数据(大部分值较小)
np.random.seed(42)
data = np.random.exponential(scale=2, size=100)  # 指数分布数据

# 为了可读性,取部分数据
scores = pd.Series(data[:20])

print("=== 原始数据 ===")
print(scores.sort_values().values)

# 2. 使用 pd.qcut() 将数据分成 4 个分位数组( quartile)
result = pd.qcut(scores, q=4)
print("\n=== pd.qcut(scores, q=4) 四分位分箱 ===")
print(result.value_counts().sort_index())

运行结果预期:

=== 原始数据 ===
[ 0.078  0.29   0.68   0.91   1.03  1.06  1.23  1.3   1.5   1.69
  1.86  2.01  2.12  2.3   2.32  2.42  3.03  3.39  5.29  7.39]

=== pd.qcut(scores, q=4) 四分位分箱 ===
(0.0783, 1.547]     5
(1.547, 2.315]     5
(2.315, 3.151]     5
(3.151, 7.393]     5
dtype: int64

代码解析:

  1. 对于指数分布的数据,如果使用等宽分箱,大部分数据会集中在一个箱内。
  2. pd.qcut() 确保每个箱内有大约相同数量的样本(这里是 5 个,正好是 20/4)。
  3. 分位点是根据数据的实际分布计算出来的,而不是均匀划分的。

示例 2:指定自定义分位数

可以通过 q 参数指定任意的分位数,如十分位数、百分位数等。

实例

import pandas as pd
import numpy as np

# 1. 创建数据
df = pd.DataFrame({
    'name': ['Student_' + str(i) for i in range(1, 11)],
    'score': [65, 78, 82, 55, 90, 72, 68, 85, 45, 95]
})

print("=== 学生成绩数据 ===")
print(df)

# 2. 按自定义分位数分箱 [0, 0.3, 0.7, 1.0] 表示 30% 70% 100%
result = pd.qcut(df['score'], q=[0, 0.3, 0.7, 1.0])
print("\n=== 按 30% 和 70% 分位数分箱 ===")
print(result)

# 3. 添加自定义标签
labels = ['及格', '良好', '优秀']
result_labeled = pd.qcut(df['score'], q=3, labels=labels)
print("\n=== 添加自定义标签 ===")
print(result_labeled)

运行结果预期:

=== 学生成绩数据 ===
      name  score
0  Student_1     65
1  Student_2     78
2  Student_3     82
3  Student_4     55
4  Student_5     90
5  Student_6     72
6  Student_7     68
7  Student_8     85
8  Student_9     45
9  Student_10    95

=== 按 30% 和 70% 分位数分箱 ===
0      (44.999, 65.8]
1      (65.8, 86.4]
2      (65.8, 86.4]
3      (44.999, 65.8]
4      (86.4, 95.0]
5      (65.8, 86. 86.4]
6      (0.0, 44.999]
7      (44.999, 65.8]
8      (0.0, 44.999]
9      (65.8, 86.4]
10     (65.8, 86.4]

代码解析:

  • q=[0, 0.3, 0.7, 1.0] 定义了 0-30%(低分),30%-70%(中等),70%-100%(高分)三个区间。
  • 使用 labels 参数可以给每个区间命名,代替默认的区间表示。

示例 3:cut vs qcut 对比

通过对比可以更清楚地理解 cutqcut 的区别。

实例

import pandas as pd
import numpy as np

# 1. 创建有偏斜的数据(大部分值较小)
data = pd.Series([1, 1, 1, 1, 1, 1, 1, 1, 1, 10, 20, 30, 40, 50])

print("=== 原始数据 ===")
print(data.values)

# 2. 等宽分箱 (pd.cut)
print("\n=== pd.cut 等宽分箱 ===")
cut_result = pd.cut(data, bins=4)
print(cut_result.value_counts().sort_index())

# 3. 等量分箱 (pd.qcut)
print("\n=== pd.qcut 等量分箱 ===")
qcut_result = pd.qcut(data, q=4)
print(qcut_result.value_counts().sort_index())

运行结果预期:

=== 原始数据 ===
[ 1  1  1  1  1  1  1  1  1 10 20 30 40 50]

=== pd.cut 等宽分箱 ===
(0.975, 13.25]    10   # 10 个值在这个区间
(13.25, 25.5]      1
(25.5, 37.75]      1
(37.75, 50.0]      2   # 2 个值在这个区间
dtype: 50

=== pd.qcut 等量分箱 ===
(0.999, 7.75]      4   # 约 1/4 的数据
(7.75, 25.0]       4
(25.0, 42.5]       4
(10.0, 50.0]       4   # 约 1/4 的数据

代码解析:

  • pd.cut() 将数据范围等分为 4 份,但由于数据高度偏斜,大部分值(9 个 1)落在第一个区间内。
  • pd.qcut() 确保每个区间包含相同数量的数据点(4 个),即使区间宽度差异很大。

提示: pd.cut() 适用于数据分布均匀或需要固定宽度区间的情况。pd.qcut() 适用于数据分布不均或需要按排名/百分比划分的情况。

Pandas 常用函数 Pandas 常用函数