当我们处理数据时,有时需要将一个连续的数值型变量划分为离散的分类变量,这个过程被称为离散化或者分箱。在Python中,使用Pandas的 cut()
方法可以非常方便地实现这个过程。
cut()
方法的基本用法
cut()
方法的基本用法如下:
pandas.cut(x, bins, right=True, labels=None, retbins=False, precision=3, include_lowest=False, duplicates='raise', ordered=True)
参数说明:
- x:要进行分析的数值型数据序列。
- bins:用于离散化的数值序列。有三种方式可以指定
bins
: - 一个整数 n,表示将 x 划分为 n 个等宽的区间。
- 一个序列,按照该序列中的值将 x 划分为若干个离散的区间。
- 一个字符串,表示使用某种算法将 x 划分为若干个离散的区间,如
"quantile"
表示使用分位数划分,"uniform"
表示等宽划分。 - right:布尔类型,表示区间是否包括右端点,缺省值为 True。
- labels:可选参数,用于指定区间的标签,如果不指定则使用区间的序号作标签。
- retbins:布尔类型,表示是否返回离散化的区间,缺省值为 False。
- precision:表示小数精度,缺省值为 3。
- include_lowest:布尔类型,表示是否将最小值包含在第一个区间中,缺省值为 False。
- duplicates:字符串类型,表示如果出现相同的边界值(如 bin1=bin2),是把值划入前一个区间还是后一个区间。取值可以为 ‘raise'(默认值)、’drop’ 或 ‘raise’ 中的任意一个。其中 ‘drop’ 表示将重复的值划入前一个区间,’raise’ 表示抛出异常。需要注意的是,’drop’ 和 ‘raise’ 只影响箱线图的生成,不影响实际的数据处理结果。
- ordered:布尔类型,表示生成的标签是否有序。
下面是一个例子,将年龄数据划分为年龄段,其中区间为 [0, 18),[18, 30),[30, 60),[60, 100):
import pandas as pd
data = [16, 20, 35, 45, 80, 100]
bins = [0, 18, 30, 60, 100]
labels = ['青少年', '青年', '中年', '老年']
result = pd.cut(data, bins, labels=labels)
print(result)
# 输出结果:
# [青少年, 青年, 中年, 中年, 老年, 老年]
# Categories (4, object): [青少年 < 青年 < 中年 < 老年]
输出结果中,Categories
是一个分类类型,其中 [青少年 < 青年 < 中年 < 老年]
表示四个年龄段的序列,也可以理解为按这个序列的顺序排列标签。
cut()
方法的返回值是一个包含标签的 pandas.Series
类型数据,这个数据的长度、数据类型和入参x
的一致,因此,可以直接将其赋值给 DataFrame 的新列。
cut()
方法的高级用法
cut()
方法还有一些高级用法,例如:
按照分位数划分
有时我们不希望按等宽划分,而是按照变量的分布情况划分,这时可以使用 "quantile"
参数指定按照分位数划分:
import pandas as pd
import numpy as np
data = np.random.normal(0, 1, 10000)
result = pd.cut(data, bins=4, labels=False, retbins=True, precision=2).values
print(result[1])
print(result[0].categories)
输出:
[-4.04 -1.05 1.88 4.87]
Index(['(-4.04, -1.05]', '(-1.05, 1.88]', '(1.88, 4.87]',
'(4.87, 7.86]'],
dtype='object')
cut()
方法的输出被赋值为一个 Pandas 中的 Categorical 类型,其中 categories 维护了分箱后的标签,astype(int) 可以查看每个数据的标签。
使用 qcut()
方法
有时候我们希望每个区间包含的数据量大致相同,针对这种需求,Pandas 还提供了 qcut()
方法,该方法按照分位数划分数据,但是每个区间的数据量是尽可能相等的,示例代码如下:
import numpy as np
import pandas as pd
data = np.random.normal(0, 1, 1000)
result = pd.qcut(data, 4)
print(result.value_counts())
输出:
(-3.3209999999999997, -0.609] 250
(-0.609, 0.0182] 250
(0.0182, 0.625] 250
(0.625, 3.8289999999999997] 250
dtype: int64
qcut()
方法默认根据分位数,将数据分为4个等量的区间,每个区间内部的数据量以及数据的取值范围都尽量相等。
总结
cut()
方法是 Pandas 中非常常用的方法,可以将一个连续的数值型变量快速离散化为分类变量,常用于数据清洗和探索性分析。虽然 cut()
方法的参数较多,但是基本用法简单易懂,高级用法也比较灵活,可以根据需要选择。