pandas之cut

cut( )用来把一组数据分割成离散的区间。

cut(x, bins, right=True, labels=None, retbins=False, precision=3, include_lowest=False, duplicates='raise')
# x:被切分的数据,必须是一维
# bins:①int型整数:将x按照数值大小平均分成分成bins份,x的范围在最左侧和最右侧分别扩展0.1%以包括最大值和最小值
     #②标量序列:自定义分组的每个区间,此时严格按照给定的区间分割,x最左和最右不扩展
     #③pandas.IntervalIndex
# right:布尔值,默认为True,表示分割后包含区间右侧值不包含左侧值,False表示分割后包含左侧值不包括右侧值
# labels:分组后bins的标签,默认为None显示分割后属于的区间
# retbins:返回结果中是否包括bins,一般bins参数使用整数时
# precision:保留的小数点位数,默认为3
# include_lowest:如果自定义标量序列分组,第一个区间是否包含左侧最小值
# duplicates:是否允许区间重复

 

bins设置为整数,将一维数组平均分为5份

arr = np.array([1,77,10,89,36,12,58,62,5,40,32,18,20,25,30,100])
c = pd.cut(arr,5,precision=1)
print(c)
# [(0.9, 20.8], (60.4, 80.2], (0.9, 20.8], (80.2, 100.0], (20.8, 40.6], ..., (0.9, 20.8], (0.9, 20.8], (20.8, 40.6], (20.8, 40.6], (80.2, 100.0]]
# Length: 16
# Categories (5, interval[float64]): [(0.9, 20.8] < (20.8, 40.6] < (40.6, 60.4] < (60.4, 80.2] < (80.2, 100.0]]

系统自动根据数组中数值的大小将原数据平均分为5分,每个区间间隔为19.8。整个区间的起点为(1,100],由于右侧包含了100因此最大区间的最大值无需扩展,而由于不包括1,因此最小区间的最小值需向左扩展0.1% * 100 = 0.1,即1-0.1 = 0.9。

设置retbins=True,会将分割区间以数组形式显示出来,这个参数一般在bins设置为整数时使用,因为其他bins两种方式都是自定义了这个区间。

arr = np.array([1,5,10,40,36,12,58,62,77,89,100,18,20,25,30,32])
c = pd.cut(arr,5,precision=1,retbins = True)
print(c)
# ([(0.9, 20.8], (0.9, 20.8], (0.9, 20.8], (20.8, 40.6], (20.8, 40.6], ..., (0.9, 20.8], (0.9, 20.8], (20.8, 40.6], (20.8, 40.6], (20.8, 40.6]]
# Length: 16
# Categories (5, interval[float64]): [(0.9, 20.8] < (20.8, 40.6] < (40.6, 60.4] < (60.4, 80.2] < (80.2, 100.0]], \
# array([ 0.901, 20.8 , 40.6 , 60.4 , 80.2 , 100. ]))

 

bins自定义分组序列,并指定lables

c = pd.cut(arr,bins = [1,5,18,35,50,100],labels = ['幼儿','少年','青年','中年','老年'],precision=1)
print(c)
# [NaN, 老年, 少年, 老年, 中年, ..., 少年, 青年, 青年, 青年, 老年]
# Length: 16
# Categories (5, object): [幼儿 < 少年 < 青年 < 中年 < 老年]

上述示例的意思是,将原数组按照1-5、5-18、18-35、35-50、50-100(左开右闭)的区间进行划分,划分后分别对应幼儿、少年、青年、中年、老年。

但是由于默认为左开区间所以无法将最小值划到一个给定的区间(如果设置right=False则最大值无对应区间),因此原数组中的第一个数1返回的是NaN,可以设置参数include_lowest=True,则可将最小是包含进去。

c = pd.cut(arr,bins = [1,5,18,35,50,100],labels = ['幼儿','少年','青年','中年','老年'],precision=1,include_lowest=True)
print(c)
# [幼儿, 老年, 少年, 老年, 中年, ..., 少年, 青年, 青年, 青年, 老年]
# Length: 16
# Categories (5, object): [幼儿 < 少年 < 青年 < 中年 < 老年]

 

 

上述例子的返回结果包含三项,第一项是每个数属于哪个区间,第二个是原数组长度,第三个是Category对象

如果只想显示第一项、即数组中的每个值属于哪个区间,可设置为labels = False

c= pd.cut(arr,bins = [1,5,18,35,50,100],labels=False,include_lowest=True)
print(c)
# [0 0 1 3 3 1 4 4 4 4 4 1 2 2 2 2]

 

posted @ 2019-08-12 21:48  Forever77  阅读(626)  评论(0编辑  收藏  举报