Python中的Pandas.cut()方法

  • Post category:Python

当我们处理数据时,有时需要将一个连续的数值型变量划分为离散的分类变量,这个过程被称为离散化或者分箱。在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() 方法的参数较多,但是基本用法简单易懂,高级用法也比较灵活,可以根据需要选择。