Python: 出现频率
我有一串整数,想要知道每个整数出现的频率。这个问题在这里讨论过。
我遇到的问题是,我用的方法给出的频率是浮点数,而我的数据集只包含整数。这是为什么呢?我该如何从我的数据中获取整数的频率呢?
我正在使用pyplot.histogram来绘制一个显示出现频率的直方图。
import numpy as np
import matplotlib.pyplot as plt
from numpy import *
data = loadtxt('data.txt',dtype=int,usecols=(4,)) #loading 5th column of csv file into array named data.
plt.hist(data) #plotting the column as histogram
我得到了直方图,但我注意到如果我用“print”来输出hist(data),
hist=np.histogram(data)
print hist(data)
我得到的是:
(array([ 2323, 16338, 1587, 212, 26, 14, 3, 2, 2, 2]),
array([ 1. , 2.8, 4.6, 6.4, 8.2, 10. , 11.8, 13.6, 15.4,
17.2, 19. ]))
这里第二个数组代表值,第一个数组代表出现的次数。
在我的数据集中,所有的值都是整数,为什么第二个数组会有浮点数呢?我该如何获取整数的频率呢?
更新:
这个解决了我的问题,谢谢Lev的回复。
plt.hist(data, bins=np.arange(data.min(), data.max()+1))
为了避免创建一个新问题,我该如何让每个整数的柱子“居中”呢?比如,我想让整数3的柱子占据2.5到3.5之间的空间,而不是在3和4之间。
3 个回答
(虽然来得有点晚,但我想补充一个关于 seaborn
的实现)
上面问题的 Seaborn 实现:
在写这段内容时,seaborn.__version__ = 0.9.0
。
加载所需的库,并设置一些模拟数据。
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
data = np.array([3]*10 + [5]*20 + [7]*5 + [9]*27 + [11]*2)
使用 seaborn.distplot
绘制数据:
使用指定的区间,这些区间是根据上面的问题计算出来的。
sns.distplot(data,bins=np.arange(data.min(), data.max()+1),kde=False,hist_kws={"align" : "left"})
plt.show()
尝试 numpy
内置的分箱方法
我使用了下面的 doane
分箱方法,它生成了整数区间,可能值得尝试一下 来自 numpy.histogram_bin_edges
的标准分箱方法,因为这就是 matplotlib.hist()
如何对数据进行分箱的方式。
sns.distplot(data,bins="doane",kde=False,hist_kws={"align" : "left"})
plt.show()
生成了下面的直方图:
你可以使用 itertools
里的 groupby
,就像在如何计算列表中元素的频率?中所示的那样。
import numpy as np
from itertools import groupby
freq = {key:len(list(group)) for key, group in groupby(np.sort(data))}
如果你不指定要用什么样的区间,np.histogram
和 pyplot.hist
会默认使用10个相等的区间。第一个区间的左边界是最小值,而最后一个区间的右边界是最大值。
这就是为什么区间的边界是浮点数的原因。你可以使用 bins
这个参数来选择其他的区间,比如:
plt.hist(data, bins=np.arange(data.min(), data.max()+1))
补充:将所有区间向左移动最简单的方法可能就是从所有区间的边界减去0.5:
plt.hist(data, bins=np.arange(data.min(), data.max()+1)-0.5)
还有一种方法可以达到相同的效果(如果有非整数的话,这种方法就不一样了):
plt.hist(data, bins=np.arange(data.min(), data.max()+1), align='left')