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

Pandas pd.cut() 函数

Pandas 通用函数 Pandas 常用函数


pd.cut() 是 Pandas 库中用于将连续数据分箱(Binning)的函数。它将数值数据按照指定的区间划分为离散的类别,非常适合用于数据分析中的分组统计和可视化。

分箱操作在数据分析中非常常见,例如将年龄划分为"青少年"、"中年人"、"老年人",或将成绩划分为"不及格"、"及格"、"良好"、"优秀"等。

单词释义cut 意为"切割",在这里指将连续的数据区间"切割"成多个离散的区间。


基本语法与参数

pd.cut() 是 Pandas 库的顶级函数,用于将连续变量离散化。

语法格式

pd.cut(x, bins, right=True, labels=None, retbins=False, precision=3, include_lowest=False)

参数说明

  • 参数x
    • 类型: 数组-like 对象,如列表、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[1]}")

运行结果预期:

=== 原始分数 ===
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.   ]

代码解析:

  1. bins=3 表示将数据自动分成 3 个等宽的区间。
  2. Pandas 会根据数据的最小值和最大值自动计算区间边界。
  3. 返回的是 Categorical 类型,每个值是一个 Interval(区间)对象。
  4. 默认使用右闭区间,即 (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())

运行结果预期:

=== 原始成绩
[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)

运行结果预期:

=== 默认右闭区间 [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 指定的范围,会产生 NaN
  • bins 的边界必须是单调递增的
  • 使用自定义标签时,标签数量必须比边界数量少 1
  • 分箱后的结果是 Categorical 类型,可以使用字符串方法处理

Python math 模块 Pandas 常用函数