Спасибо всем за все предложения. Никто не делает то, что мне было нужно (вероятно, потому что мой первоначальный вопрос не был достаточно ясен), но они действительно помогли мне понять, что делать, поэтому я решил опубликовать свой собственный ответ (я надеюсь, что это то, что я должен сделать какЯ относительно новичок в том, чтобы быть активным членом stackoverflow ...)
Мне больше всего понравилось векторизованное предложение @ yatu, потому что оно будет лучше масштабироваться с большими наборами данных, но я стремлюсь не только автоматически вычислять биныно также определите минимальное количество бинов, необходимое для покрытия набора данных.
Это мой предложенный алгоритм:
- Размер бина определяется так, чтобы bin_max_i / bin_min_i была постоянной:
bin_max_i / bin_min_i = bin_ratio
Определите количество лотков для требуемого размера лотка (bin_ratio):
data_ratio = data_max / data_min
n_bins = math.ceil( math.log(data_ratio) / math.log(bin_ratio) )
Установите нижнюю границу для наименьшего бина, чтобы в него помещалась наименьшая точка данных:
bin_min_0 = data_min
Создание n неперекрывающихся ячеек, соответствующих условиям:
bin_min_i+1 = bin_max_i
bin_max_i+1 = bin_min_i+1 * bin_ratio
Прекратите создавать дополнительные ячейки после того, как все наборы данных можно будет разделить между уже созданными ячейками. Другими словами, остановитесь один раз:
bin_max_last > data_max
Вот фрагмент кода:
import math
import pandas as pd
bin_ratio = 1.20
data = pd.Series(np.arange(2,12))
data_ratio = max(data) / min(data)
n_bins = math.ceil( math.log(data_ratio) / math.log(bin_ratio) )
n_bins = n_bins + 1 # bin ranges are defined as [min, max)
bins = np.full(n_bins, bin_ratio) # initialise the ratios for the bins limits
bins[0] = bin_min_0 # initialise the lower limit for the 1st bin
bins = np.cumprod(bins) # generate bins
print(bins)
[ 2. 2.4 2.88 3.456 4.1472 4.97664
5.971968 7.1663616 8.59963392 10.3195607 12.38347284]
Теперь я настроен на построение гистограммы данных:
data.hist(bins=bins)