Ответ 1
Учитывая название вашего вопроса, я буду считать, что размер дискретизации постоянный.
Вы можете найти этот размер дискретизации (или, по крайней мере, строго, n раз этот размер, поскольку у вас могут не быть двух смежных сэмплов в ваших данных)
np.diff(np.unique(data)).min()
Это находит уникальные значения в ваших данных (np.unique
), находит различия между ними (np.diff
). Уникальный необходим, чтобы вы не получали нулевых значений. Затем вы найдете минимальную разницу. Там могут быть проблемы, когда постоянная дискретизации очень мала - я вернусь к этому.
Далее - вы хотите, чтобы ваши значения находились в середине бункера - ваша текущая проблема связана с тем, что и 9, и 10 находятся по краям последнего бина, который автоматически загружает matplotlib, поэтому вы получаете два образца в одном бункере.
Итак - попробуйте следующее:
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
, с которым были созданы данные. Однако - с трюком смещения бункеров на половину d
, чтобы получить значения в середине - это не должно иметь значения , если ваша дискретизация очень мала, поэтому ваш вниз в пределах точности от float или у вас есть 1000 ящиков, а разница между обнаруженной d
и "реальной" дискретизацией может нарастать до такой точки, что один из бункеров "пропускает" точку данных. Это то, что нужно знать, но, вероятно, не ударит вас.
Примерный график для вышеописанного
Неравномерная дискретизация/наиболее подходящие ячейки...
Для более сложных случаев вам может понравиться в этом сообщении в блоге, которое я нашел. Это рассматривает способы автоматического "обучения" лучшим ширинам бинов из (непрерывных/квазинепрерывных) данных, ссылаясь на несколько стандартных методов, таких как правило Стурджа и Фридмана и Diaconis ", прежде чем разработать собственный метод байесовского динамического программирования.
Если это ваш прецедент - вопрос гораздо шире и не подходит для окончательного ответа на переполнение стека, хотя, надеюсь, ссылки помогут.