pandas冷门又很强大的技巧-cut

如果有一组数据,需要根据不同的范围返回一个标签,比如,一组成绩,60分以下不合格,60-80:良,80-95:优秀,我们可以通过判断来实现这个功能,但是如果让你平均分成4份,可能就会稍微麻烦点,在pandas中提供了一个可以实现上述功能的方法:

cut

参数解释:

pandas.cut

pandas.cut(x, bins, right=True, labels=None, retbins=False, precision=3, include_lowest=False, duplicates='raise')[source]

Bin值为离散间隔。

需要将数据值分段并排序到箱中时使用cut。 此函数对于从连续变量转换为分类变量也很有用。 例如,cut可以将年龄转换为年龄范围组。 支持分箱到相同数量的箱柜或预先指定的箱柜阵列。

x : array-like

数组或者序列,但是必须是一维的

bins : int, sequence of scalars, or IntervalIndex

int:定义x范围内的等宽bin的数量。 x的范围在每一侧扩展0.1%,以包括x的最小值和最大值。标量序列:定义bin边缘,允许不均匀的宽度。 没有扩展x的范围。IntervalIndex:定义要使用的精确bin。 请注意,bin的IntervalIndex必须不重叠。

right : bool, default True

指示是否包含最右边。 如果right == True(默认值),则bin [1,2,3,4]表示(1,2], (2,3], (3,4]。当bin是IntervalIndex时,该参数被忽略。

labels : array or bool, optional

指定返回的bin的标签。 必须与生成的箱柜长度相同。 如果为False,则仅返回bin的整数指示符。 这会影响输出容器的类型(见下文)。 当bin是IntervalIndex时,将忽略此参数。

retbins : bool, default False

表示是否将分割后的bins返回,当bins为一个int型的标量时比较有用,这样可以得到划分后的区间,默认为False。

precision : int, default 3

保留区间小数点的位数,默认为3.

include_lowest : bool, default False

bool型的参数,表示区间的左边是开还是闭的,默认为false,也就是不包含区间左部(闭)。

duplicates : {default ‘raise’, ‘drop’}, optional

是否允许重复区间。有两种选择:raise:不允许,drop:允许。

返回值:

out:一个pandas.Categorical, Series或者ndarray类型的值,代表分区后x中的每个值在哪个bin(区间)中,如果指定了labels,则返回对应的label。

bins:分隔后的区间,当指定retbins为True时返回。

实例:

如果传入的是一个数组:

pd.cut(np.array([1, 7, 5, 4, 6, 3]), 3)

把它分成3份:

返回的是每个数据所在的区间

如果我们想看一下如何划分区间的:

pd.cut(np.array([1, 7, 5, 4, 6, 3]), 3, retbins=True)

如果想给每个划分的区间设置一个标签:

pd.cut(np.array([1, 7, 5, 4, 6, 3]), 3, labels=["bad", "medium", "good"])

返回的就不在是对应的划分区间,而是划分区间对应的标签,

需要注意的是标签要和划分的区间长度要相等

现在我们传入一个序列

s = pd.Series(np.array([2, 4, 6, 8, 10]),
index=['a', 'b', 'c', 'd', 'e'])

现在分成3组:

pd.cut(s, 3)

查看分的组:

pd.cut(s, 3,retbins=True)

给每个分组添加标签:

pd.cut(s, 3, labels=["bad", "medium", "good"])

如果传入bins一个分好的组:

pd.cut(s, bins=[0, 2, 4, 6, 8, 10], labels=False, retbins=True, right=False)

接下来需要讲一下分组的边界问题:

主要涉及这几个参数:right、include_lowestduplicates

right:默认为True

在默认情况下,每段值是不包含左边的界值,包含右边的界值(如上图)。

如果我们要选择左边界,那么只需要加一个参数:right = False就可以。

include_lowest:默认为FALSE

第一个间隔是否应该是包含在内

bins给定分组的第一个值是否包含在内,默认是不包含的,可以修改为True

duplicates:{default ‘raise’, ‘drop’}, optional

是否允许重复区间。有两种选择:raise:不允许,drop:允许。

扩展应用:groupby中利用cut分组当做分组的键:

新建数据:

df = pd.DataFrame({'Age': np.random.randint(20, 70, 100),
'Sex': np.random.choice(['Male', 'Female'], 100),
'number_of_foo': np.random.randint(1, 20, 100)})
df

利用分好的组当做分组的键:

age_groups = pd.cut(df['Age'], bins=[19,40,65,np.inf])
df.groupby(age_groups).mean()