有时我不得不用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/