numpy.histogram_bin_edges
numpy.histogram_bin_edges(a, bins=10, range=None, weights=None)
Функция histogram_bin_edges() вычисляет границы интервалов для ячеек гистограммы.
-
- a - массив NumPy или подобный массиву объект.
- Входные данные. Многомерные массивы сжимаются до одной оси.
- bins - целое число, последовательность целых чисел или строка (необязательный параметр).
-
Если указано целое число, то оно определяет количество интервалов равной ширины всех ячеек (по умолчанию 10 ячеек). Если указана последовательность целых чисел, то границы интервалов определяют соседние числа в данной последовательности.
В NumPy начиная с версии 1.11.0 в качестве данного параметра можно указывать строку с названием метода расчета оптимальной ширины ячеек.
- 'auto' - максимальные значения 'sturges' и 'fd'. Обеспечивает наилучшую производительность;
- 'fd' - метод оценки Фридмана-Диакониса, который учитывает размер данных и их изменчивость. Устойчив к выбросам и считается наиболее надежным;
- 'doane' - улучшенная версия 'sturges', которая лучше всего подходит для данных с ненормальным распределением значений;
- 'scott' - метод, который учитывает изменчивость и размер данных, но является менее надежным;
- 'rice' - учитывает только размер данных и обычно переоценивает количество необходимых ячеек;
- 'sturges' - R-метод, который учитывает только размер данных. Оптимален только для данных с гаусовым распределением значений. Для больших негаусовых данных недооценивается необходимое количество ячеек;
- 'sqrt' - метод на основе квадратного корня от размера данных, самый быстрый и простой метод, но может подойти не для всех данных.
- range - (float_1, float_2) (необязательный параметр).
-
Определяет минимальное и максимальное значение ширины ячеек, при этом значения выходящие за пределы диапазона игнорируются. Если
range = None
то границы определяются интервалом(a.min(), a.max())
. Должно выполняться условиеfloat_1 < float_2
.Если в параметре
bins
указана строка с методом расчета ширины, то значения вrange
повлияют на эти вычисления. В этом случае по прежнему будет вычисляться оптимальная ширина ячеек, но только на основе тех данных, которые находятся в пределах указанного интервала. В любом случае, количество ячеек будет заполнять весь интервал, даже в тех участках, которые не содержат никаких данных. - weights - массив NumPy или подобный массиву объект (необязательный параметр).
-
Массив весовых коэфициентов той же формы что и
a
. Каждое значение вa
добавляет величину к соответствующей ячейке в соответствии с указанным весом (который по умолчанию считается равным 1). В настоящее время данный параметр не используется при вычислении, но планируется его введение в будущих версиях.
-
- результат - массив NumPy
- Массив с границами ячеек для подсчета одномерной гистограммы исходных данных.
Примеры
По умолчанию, вне зависимости от размера данных, количество ячеек равно 10 (границы ячеек определяются значениями возвращаемого массива):
>>> import numpy as np
>>>
>>> a = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
>>>
>>> np.histogram_bin_edges(a)
array([1. , 1.3, 1.6, ..., 3.4, 3.7, 4. ])
>>>
>>> len(np.histogram_bin_edges(a))
11
Если в параметре bins
уже указана последовательность с границами ячеек, то она возвращается без изменений:
>>> np.histogram_bin_edges(a, [1, 2])
array([1, 2])
>>>
>>> np.histogram_bin_edges(a, [1, 2, 3, 4])
array([1, 2, 3, 4])
Вычисленный массив с границами может использоваться повторно, для расчета других гистограмм:
>>> x = [1, 1, 1, 2, 2, 3, 3, 4]
>>> y = [1, 1, 2, 2, 2, 3, 4, 4]
>>>
>>> edges = np.histogram_bin_edges(x, bins = 'auto')
>>>
>>> np.histogram(x, edges)
(array([3, 2, 2, 1], dtype=int32), array([1. , 1.75, 2.5 , 3.25, 4. ]))
>>>
>>> np.histogram(y, edges)
(array([2, 3, 1, 2], dtype=int32), array([1. , 1.75, 2.5 , 3.25, 4. ]))
Методы расчета границ ячеек
Допустим у нас естьдва набора данных по 7000 и 100 случайных чисел с гамма распределением. Давайте сначала визуально сравним гистограммы с ячейками рассчитанными разными методами:
import numpy as np
import matplotlib.pyplot as plt
rng = np.random.RandomState(777)
x = rng.gamma(3, 2, size = 7000)
y = rng.gamma(3, 2, size = 100)
fig, axes = plt.subplots(6, 2)
method = ['auto', 'fd', 'scott', 'rice', 'sturges', 'sqrt']
for i in range(6):
hist, bin_edges = np.histogram(x, bins = method[i])
# Позиции серидин ячеек
pos = bin_edges[:-1] + np.diff(bin_edges)/2
axes[i][0].bar(pos, hist)
axes[i][0].set_title('x - ' + method[i])
for i in range(6):
hist, bin_edges = np.histogram(y, bins = method[i])
# Позиции серидин ячеек
pos = bin_edges[:-1] + np.diff(bin_edges)/2
axes[i][1].bar(pos, hist)
axes[i][1].set_title('y - ' + method[i])
# Меняем расстояние между областями Axes:
fig.subplots_adjust(hspace=1, wspace = 0.1)
fig.set_figwidth(12) # ширина и
fig.set_figheight(18) # высота "Figure"
plt.show()
bins = 'auto'
Данный метод оценки выбирает лучшую оценку вычисленную методами 'sturges' и 'fd'. Для небольших наборов данных выбирается значение 'sturges', а для больших всегда используется 'fd'. Точка переключения с одного метода на другой составляет порядка 1000 элементов.
>>> import matplotlib.pyplot as plt
>>>
>>> hist_x, bin_edges = np.histogram(x, bins = 'auto')
>>>
>>> plt.bar(bin_edges[:-1], hist_x)
>>> plt.title('x - auto')
>>> plt.show()
График для небольших наборов данных
>>> hist_y, bin_edges = np.histogram(y, bins = 'auto')
>>>
>>> plt.bar(bin_edges[:-1], hist_y)
>>> plt.title('y - auto')
>>> plt.show()
bins = 'fd'
Ширина ячеек обратнопропорциональна кубическому корню от количества элементов в массиве и прямопропорциональна межквартильному диапазону (IQR). Подходит для больших наборов данных и не подходит для маленьких:
>>> hist_x, bin_edges = np.histogram(x, bins = 'fd')
>>> plt.bar(bin_edges[:-1], hist_x)
>>> plt.title('x - fd')
>>> plt.show()
>>> hist_y, bin_edges = np.histogram(y, bins = 'fd')
>>> plt.bar(bin_edges[:-1], hist_y)
>>> plt.title('y - fd')
>>> plt.show()
bins = 'scott'
Ширина ячеек обратнопропорциональна кубическому корню от количества элементов в массиве и прямопропорциональна стандартному отклонению значений в наборе. Подходит для больших наборов данных и не подходит для маленьких. Не устойчив к выбросам, а в отсутствии выбросов, практически, совпадает с методом 'fd':
>>> hist_x, bin_edges = np.histogram(x, bins = 'scott')
>>> plt.bar(bin_edges[:-1], hist_x)
>>> plt.title('x - scott')
>>> plt.show()
>>> hist_y, bin_edges = np.histogram(y, bins = 'scott')
>>> plt.bar(bin_edges[:-1], hist_y)
>>> plt.title('y - scott')
>>> plt.show()
bins = 'rice'
Количество ячеек прямопропорционально кубическому корню от количества элементов в массиве, что может приводить переоцениванию необходимого количества ячеек и не учитывает изменчивость данных:
>>> hist_x, bin_edges = np.histogram(x, bins = 'rice')
>>> plt.bar(bin_edges[:-1], hist_x)
>>> plt.title('x - rice')
>>> plt.show()
>>> hist_y, bin_edges = np.histogram(y, bins = 'rice')
>>> plt.bar(bin_edges[:-1], hist_y)
>>> plt.title('y - rice')
>>> plt.show()
bins = 'doane'
Улучшенная версия метода 'sturges', которая лучше всего подходит для данных с ненормальным распределением и пытается учесть перекосы в них:
>>> hist_x, bin_edges = np.histogram(x, bins = 'doane')
>>> plt.bar(bin_edges[:-1], hist_x)
>>> plt.title('x - doane')
>>> plt.show()
>>> hist_y, bin_edges = np.histogram(y, bins = 'doane')
>>> plt.bar(bin_edges[:-1], hist_y)
>>> plt.title('y - doane')
>>> plt.show()
bins = 'sqrt'
Количество ячеек прямопропорционально квадратному корню от количества элементов в массиве - самый простой и быстрый метод оценивания, но абсолютно не учитывающий изменчивость данных и плохо подходящий для небольших данных:
>>> hist_x, bin_edges = np.histogram(x, bins = 'sqrt')
>>> plt.bar(bin_edges[:-1], hist_x)
>>> plt.title('x - sqrt')
>>> plt.show()
>>> hist_y, bin_edges = np.histogram(y, bins = 'sqrt')
>>> plt.bar(bin_edges[:-1], hist_y)
>>> plt.title('y - sqrt')
>>> plt.show()