鉴于您的问题的标题,我将假设离散化大小是恒定的。
您可以找到这个离散化大小(或者至少,严格地说,是该大小的 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 的“真实”值。但是 - 通过将 bin 移动一半 d 以获得中间值的技巧 - 这无关紧要除非您的离散化非常小,所以你在浮点精度的限制或你有1000个箱子,检测到的d和“真实”离散化之间的差异可以达到这样的程度其中一个垃圾箱“错过”了数据点。这是需要注意的事情,但可能不会打击你。
上面的示例图是
非均匀离散化/最合适的 bin...
对于更复杂的情况,您可能希望查看this blog post I found。本文着眼于从(连续/准连续)数据中自动“学习”最佳 bin 宽度的方法,在开发自己的贝叶斯动态规划方法之前参考多种标准技术,例如 Sturges' rule and Freedman and Diaconis' rule。
如果这是您的用例 - 问题要广泛得多,可能不适合 Stack Overflow 上的明确答案,但希望这些链接会有所帮助。