include_lowest дает неожиданные результаты в pandas.cut

#python #pandas

#python #pandas

Вопрос:

Итак, следующий код (mydata — это a pandas.Series с плавающими значениями в формате X.XX с минимальным значением выше 1.195, если это имеет значение):

 bin_range =[ 1.195,  2.655,  4.115,  5.575,  7.035,  8.495,  9.955, 11.415,
       12.875]
out, bins  = pd.cut(mydata, bins=bin_range, include_lowest=True, right=True, retbins=True)
print(out.value_counts(sort=False))
print(bins)
 

Дает мне такой результат:

 (1.1940000000000002, 2.655]    19
(2.655, 4.115]                 12
(4.115, 5.575]                 17
(5.575, 7.035]                 15
(7.035, 8.495]                  5
(8.495, 9.955]                  8
(9.955, 11.415]                 2
(11.415, 12.875]                2
dtype: int64
[ 1.195  2.655  4.115  5.575  7.035  8.495  9.955 11.415 12.875]
 

И я не уверен, откуда берется «1.1940000000000002» (проблемы с плавающей запятой?) и почему он на самом деле не включен, несмотря include_lowest=True на.

Я пытаюсь распечатать таблицу частот сгенерированного мной графика гистограммы, поэтому в идеале ячейки должны быть чем-то вроде [), [),...,[] , чтобы охватывать весь диапазон, что кажется невозможным pandas.cut , если я чего-то не упускаю.

Редактировать: кажется, что из IntervalIndex -за того, что все include_lowest это уменьшает наименьшую границу на precision . Таким образом, вместо фактического включения 1.195 он превращает его в 1.194 (хотя, по-видимому, это тоже не удается)

Комментарии:

1. у меня нет прямого решения вашей проблемы, но у меня есть кое-что, что может просто помочь. Вы могли бы добавить дополнительный начальный интервал 0 — 1.195, если это не создает никаких проблем в другом месте.

Ответ №1:

Итак, на данный момент я придумал «хак», и я помещаю его здесь на случай, если это кому-то пригодится:

 out  = pd.cut(mydata, bins=phist, right=True, include_lowest=True)
z = out.value_counts(sort=False)
new = z.index.rename_categories({z.index[0]: pd.Interval(phist[0].round(3), phist[1].round(3), closed='both')})
z = z.reindex(new, fill_value=z[0])
print(z)
 

Он в основном заменяет первый интервал, но из include_lowest=True -за того, что он false , значения остаются правильными независимо от нашего ручного заполнения fill_value=z[0] .

Давая нам:

 [1.195, 2.655]      19
(2.655, 4.115]      12
(4.115, 5.575]      17
(5.575, 7.035]      15
(7.035, 8.495]       5
(8.495, 9.955]       8
(9.955, 11.415]      2
(11.415, 12.875]     2
 

Он по-прежнему не повторяет, как NumPy обрабатывает интервалы ( include_highest по какой-то причине у нас их нет, поэтому мы не можем гарантировать правильность), но все же имеет больше смысла, поскольку он не удаляет данные из наших ячеек.