给定一个数据数组或列表,如[1, 2, 2, 3, 5, 5, 7, 7.5, 9.5, 10]
,然后给定一个区间数组:[0, 4, 8, 10]
,要求依次统计数据数组在(0, 4]
,(4, 8]
以及(8, 10]
三个区间内各自出现的频数,并画出直方图。
首先随机生成0到10之间的100个整数:
data = np.random.randint(low=1, high=10 + 1, size=100, dtype='int')
print(data)
输出:
[ 8 7 1 9 8 7 8 7 7 8 3 6 10 10 9 2 2 10 1 2 2 6 6 2
7 4 5 5 8 6 5 4 3 2 8 4 3 5 10 5 9 6 4 5 4 2 8 9
7 8 7 9 7 4 2 7 7 6 3 3 6 7 8 1 10 7 7 10 4 4 6 4
5 5 10 7 1 2 8 4 6 8 9 9 6 4 9 5 6 4 4 10 2 6 9 3
4 8 4 9]
统计频数用pandas
的cut
函数可以很轻松地实现:
s = pd.cut(data, bins=[x for x in range(10 + 1)])
print(s.value_counts())
其中bins
表示区间数据。如前文所述,如果bins=[0, 4, 8, 10]
,那么就是统计data
在(0, 4]
,(4, 8]
以及(8, 10]
三个区间内各自出现的频数。
统计结果输出:
(0, 1] 9
(1, 2] 7
(2, 3] 7
(3, 4] 4
(4, 5] 12
(5, 6] 10
(6, 7] 14
(7, 8] 9
(8, 9] 18
(9, 10] 10
dtype: int64
然后获取频数:
values = s.value_counts().values
print(values)
[ 7 9 12 10 9 11 10 13 7 12]
获取横轴标签:
labels = [str(i) + '-' + str(i+1) for i in range(int(np.max(data)))]
print(labels)
['0-1', '1-2', '2-3', '3-4', '4-5', '5-6', '6-7', '7-8', '8-9', '9-10']
最后,生成dataframe并画图:
df = pd.DataFrame(values, index=labels)
df.plot(kind='bar', legend=False)
plt.xticks(rotation=0)
plt.ylabel('频数')
plt.xlabel('区间')
plt.show()