numpy - matplotlib离散值的直方图

标签 numpy matplotlib

有时我不得不用matplotlib对离散值进行直方图绘制。在这种情况下,分档的选择可能至关重要:如果使用10个分箱直方图[0、1、2、3、4、5、6、7、8、9、10],则其中一个分箱将有两次和其他人一样重要。换句话说,binsize通常应为离散化大小的倍数。

尽管这种简单的情况我自己就比较容易处理,但是没有人能自动找到可以处理此问题的库/函数的指针,包括浮点数据的情况下,由于FP,离散化大小可能会略有不同四舍五入?

谢谢。

最佳答案

给定您问题的标题,我将假设离散化大小是恒定的。
您可以找到此离散化大小(或严格地说,至少是 n 乘以该大小,因为您的数据中可能没有两个相邻的样本)

np.diff(np.unique(data)).min()
这会在您的数据(np.unique)中找到唯一值,并找到它们之间的差异(np.diff)。需要唯一性,这样您就不会得到零值。然后,您会找到最小的差异。离散常数很小的情况可能会出现问题-我将再次讨论。
接下来-您希望您的值位于bin的中间-您当前的问题是因为9和10都在matplotlib自动提供的最后一个bin的边缘,因此您在一个bin中得到了两个样本。
所以-试试这个:
import matplotlib.pyplot as plt
import numpy as np

data = range(11)
data = np.array(data)

d = np.diff(np.unique(data)).min()
left_of_first_bin = data.min() - float(d)/2
right_of_last_bin = data.max() + float(d)/2
plt.hist(data, np.arange(left_of_first_bin, right_of_last_bin + d, d))
plt.show()
这给出:

小非整数离散化
我们可以更多地测试数据集,例如
import random 

data = []
for _ in range(1000):
    data.append(random.randint(1,100))
data = np.array(data)
nasty_d = 1.0 / 597 #Arbitrary smallish discretization
data = data * nasty_d
然后,如果您通过上面的数组运行该代码,并查看代码吐出的d,您将看到
>>> print(nasty_d)
0.0016750418760469012
>>> print(d)
0.00167504187605

因此-检测到的d值不是用来创建数据的nasty_d的“实际”值。但是-通过将bins移位一半d来获取中间值的技巧-无关紧要,除非,您的离散度很小,所以您可以降低 float 的精度范围如果有1000个bin,则检测到的d和“真实”离散化之间的差异可以累积到一个bin会“丢失”数据点的程度。这是需要注意的事情,但可能不会打到您。
上面的示例图是

非均匀离散化/最合适的垃圾箱...
对于更复杂的情况,您可能希望查看this blog post I found。本文探讨了从(连续/准连续)数据中自动“学习”最佳bin宽度的方法,并在开发自己的贝叶斯动态编程方法之前引用了Sturges' rule and Freedman and Diaconis' rule等多种标准技术。
如果这是您的用例,那么这个问题就更广泛了,可能不适合堆栈溢出的确切答案,尽管希望这些链接会有所帮助。

关于numpy - matplotlib离散值的直方图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30112420/

相关文章:

python - FFT 与傅立叶分量的最小二乘拟合?

python - 如何像访问 pandas 数据框一样快速访问 numpy 数组

python - 如何使用scikit线性回归模型同时求解多个独立的时间序列

python - 增加决策树中节点的大小

python - sympy 方程中的未知数学错误(python)

python - Numpy - 在数组结果中显示十进制值

python - 创建不同形状数组的对象数组时如何防止 numpy 广播

Python:条形图 - 垂直标签 - 剪切

python - 如何在 matplotlib 输出中获得与 Latex 输出中相同的字体(-style、-size 等)?

python - 在Python中,如何继承并重写类实例上的方法,并将新版本分配给与旧版本相同的名称?