Python分箱统计元素个数
我们经常会在数据分析中碰到这样的一些问题:这组数据都有哪些值?这些值又各自出现了多少次?数据如果不多,我们直接掐指一算也就搞定了。如果数据多指头到不够用,那怎么办呢?
在pandas中,应对频数统计,我们就不得不谈一谈value_counts()了。
一、离散型数据
对于离散型数据,我们可以通过value_counts()的方法来统计各个离散值的频数情况,如下图我们先构造一个Series:
接下来我想知道,这些个品牌里头,各自出现了多少次,那我们就用value_counts()来试试:
默认情况,如上图所示,苹果一共出现了5次,紧接着是华为3次,然后三星和小米均2次,不信邪的同学可以掰手指头算算。
如果我想要升序排列呢,则传递参数ascending=True即可:
此外,我还想把他们的出现的数值改成百分比怎办,那咱们通过normalize=True即可:
二、连续型数据
对于连续型数据,思路上大同小异,只不过我们需要考虑的是,我需要把每个数据出现的频次都展示出来吗?还是说我可以把出现的频次按区间来展示呢?
为此,我们通过Excel的伪随机数生成器构造了一列数据,范围为[0, 100],总共5000条记录。我们读入pandas:
如果直接进行value_counts()的话,你会疯掉:
这样的一个统计情况,于你来说有什么意义呢?那么,我们可以对数据进行分箱频数统计。也就是说,我并不是要统计每个值出现的频次,而是数据落在每个区间的频次。我们把这些数据分成10个箱(数值出现的范围为[0, 100]),然后用value_counts(),如下:
可以看出,pandas立马给我们统计出了每个箱体数值出现的频次了,然而现在看着还是怪怪的,我们希望它的箱体是正常的升序展示出来,但现在它是按照后面的频次的降序展现的。通过更改另外一个参数,我们可以纠正这个问题:
因为该方法默认对频次进行了排序,我们只是把排序参数,也就是sort改为False,pandas就不会进行频数的排序了,这样看起来也就正常多了。
如果觉得看着数字不直观,我们还可以plot一下,直接看图:
在Excel中我们生成这些数据用的是randbetween()函数,从图中我们也大概能看出,这个函数给我们生成的,应该是均匀分布的随机数。
同样的,如果我想看百分比,则把normalize改为True即可:
另外,如果数据里有缺失值,还可以用dropna这个参数进行控制
也可以使用numpy
直方统计图:histogram
histogram(a,bins=10,range=None,weights=None,density=False);
a是待统计数据的数组;
bins指定统计的区间个数;
range是一个长度为2的元组,表示统计范围的最小值和最大值,默认值None,表示范围由数据的范围决定
weights为数组的每个元素指定了权值,histogram()会对区间中数组所对应的权值进行求和
density为True时,返回每个区间的概率密度;为False,返回每个区间中元素的个数
a = np.random.rand(100)
np.histogram(a,bins=5,range=(0,1))#在[0,0.2)有28个数,在[0.2,0.4)有18个数,以此类推
1
2
(array([28, 18, 17, 19, 18], dtype=int64),
array([ 0. , 0.2, 0.4, 0.6, 0.8, 1. ]))
1
2
若要统计的区间不等,可以将表示区间分割位置的数组传递给bins参数
np.histogram(a,bins=[0,0.4,0.8,1.0])
1
(array([46, 36, 18], dtype=int64), array([ 0. , 0.4, 0.8, 1. ]))