今天同事给我反馈个问题,就是不同列分箱后的数据总数不一样,正常来说,一个dataframe(数据对齐的情况下),不同列的长度一致,尽管不同列可能分的组数不一样,但是总数应该一样。于是就再查了一下的cut这个函数,cut有如下几个参数:
x : 是我们要传入和切分的一维数组,可以是列表,也可以是dataFrame的一列
bins : 代表切片的方式,可以自定义传入列表[a,b,c],表示按照a-b,b-c的区间来切分,也可以是数值n,直接指定分为n组
right : True/False,为True时,表示分组区间是包含右边,不包含左边,即(]; False,代表[)
labels : 标签参数,比如[低、中、高]
retbins : True/False, True返回bin的具体范围值,当bins是单个数值时很有用。(因为bin是数字的话, 划分组具体数值我们是不知道的)
precision : 存储和显示 bin 标签的精度。默认为3
include_lowest : True/False, 第一个区间是否应该是左包含的
duplicates : raise/drop, 如果bin列表里有重复,报错/直接删除至保留一个
ordered : 标签是否有序。 适用于返回的类型 Categorical 和 Series(使用 Categorical dtype)。 如果为 True,则将对生成的分类进行排序。 如果为 False,则生成的分类将是无序的(必须提供标签)
因为统计的数不一样,所以不是多了就是少了,多了的话可能是重复统计,但是看参数,特别是区间参数right,无非就两种情况,一种左开右闭或者左闭右开,但是无论那种情况,都不可能重复统计,所以不可能是统计多了,那只能是统计少了,那么哪个参数可能导致统计少呢,经过一番研究,发现include_lowest这个参数在用的时候有可能不严谨,比如说,我的数据是下面这样:
import pandas as pd
import numpy as np
df = pd.DataFrame({
'a':np.arange(10),
'b':np.arange(10),
})
df_cut = pd.cut(df['a'],bins=[0,3,6,9])
得到
0 NaN
1 (0.0, 3.0]
2 (0.0, 3.0]
3 (0.0, 3.0]
4 (3.0, 6.0]
5 (3.0, 6.0]
6 (3.0, 6.0]
7 (6.0, 9.0]
8 (6.0, 9.0]
9 (6.0, 9.0]
可以看到,虽然bins中我传了0,但是因为默认它的区间是左开右闭,所以没包含0,而且我也没加include_lowest参数,导致漏了结果,当然这个跟区间开闭参数也脱不开关系,因为一开一闭,总会漏掉一面,不是漏前面就是漏后面,所以要想统计全,需要两个参数结合使用,区间它默认用左开右闭,那就先按默认的来,当然在这种情况下,最小数据如果落在第一个区间左边界,刚好被漏掉,此时,再加一个include_lowest参数则正好能补上漏掉的数据,这样就比较完美了。加上这个参数后得到结果
import pandas as pd
import numpy as np
df = pd.DataFrame({
'a':np.arange(10),
'b':np.arange(10),
})
df_cut = pd.cut(df['a'],bins=[0,3,6,9],include_lowest=True)
df_cut
0 (-0.001, 3.0]
1 (-0.001, 3.0]
2 (-0.001, 3.0]
3 (-0.001, 3.0]
4 (3.0, 6.0]
5 (3.0, 6.0]
6 (3.0, 6.0]
7 (6.0, 9.0]
8 (6.0, 9.0]
9 (6.0, 9.0]
可以发现,已经可以把0补上了。