У меня проблема с функцией qcut в python. Моими верхними и нижними границами являются -Inf и Inf, но когда я применяю qcut с этими границами, Python возвращает эту ошибку «не может преобразовать бесконечность с плавающей запятой в целое число».
Мои друзья сказали мне, что я должен изменить Inf на 1e100 (очень большое число представляет ), чтобы qcut мог использовать. Однако возникает другая ошибка: «IndexError: только целые числа, срезы (:
), многоточие (...
), numpy.newaxis (None
) и целые или логические массивы являются допустимыми индексами»
Пример:
a1 = [-Inf, 26.6, 36.2, 38.7, 42.1, 47.2, 117.7]
a2 = [-1e100, 26.6, 36.2, 38.7, 42.1, 47.2, 117.7]
cut_range = [-Inf, 27.0, 33.0, 40.0, Inf] #For a1
cut_range = [-1e+100, 27.0, 33.0, 40.0, 1e+100] #For a2
b = pd.qcut(a, cut_range, duplicates = 'drop')
Я хочу иметь окончательный результат следующим образом:
b = ['[-Inf,27]','(33,40]','(33,40],'(40, Inf]','(40, Inf]','(40, Inf]']
or with 1e100:
b = ['[-1e100,27]','(33,40]','(33,40],'(40, 1e100]','(40, 1e100]','(40, 1e100]']
И кто-нибудь мог бы помочь мне объяснить, как Inf работает в Python и в R. Они оба Infinite, но почему они ведут себя так по-разному.
В R я попробовал функцию с Inf, и она сработала:
as.character(cut(a1,cut_range, include.lowest = TRUE))
На самом деле вам нужен pd.cut. Это потому, что вы группируете/маркируете свои данные на основе диапазонов:
a1 = [-np.inf, 26.6, 36.2, 38.7, 42.1, 47.2, 117.7]
cut_range = [-np.inf, 27.0, 33.0, 40.0, np.inf]
pd.cut(a1, bins = cut_range, include_lowest=True)
>> [(-inf, 27.0], (-inf, 27.0], (33.0, 40.0], (33.0, 40.0], (40.0, inf], (40.0, inf], (40.0, inf]]
Также обратите внимание, что qcut помечает данные на основе quantiles
, поэтому, если у вас есть [0, 0.25, 0.5, 0.75, 1]
в качестве cut_range
, данные будут разделены на 4 квантиля. Первый квантиль будет принадлежать значениям от минимума до 25-го процентиля (0-0,25). Когда вы добавляете -np.inf, не может быть отрицательного значения процентиля, и, следовательно, вы получаете ошибку.
Ах, так это проблема с -np.inf, так что 1e100 в этом случае не нужен, верно? Бв спасибо большое
searchsorted
Хотя я прокомментировал, что вам нужно pd.cut
. Я лично использую searchsorted
.
a = np.array([-np.inf, 26.6, 36.2, 38.7, 42.1, 47.2, 117.7])
cut = np.array([27.0, 33.0, 40.0])
labels = np.array([
f"({x:.1f}, {y:.1f}]"
for x, y in zip([-np.inf] + list(cut), list(cut) + [np.inf])
])
labels[cut.searchsorted(a)]
array(['(-inf, 27.0]', '(-inf, 27.0]', '(33.0, 40.0]', '(33.0, 40.0]',
'(40.0, inf]', '(40.0, inf]', '(40.0, inf]'], dtype='<U12')
В результате получается либо массив кодов cut.searchsorted(a)
, либо меток, как я показал выше. Его можно превратить в тип pandas.Categorical
, но тогда вам действительно нужно просто использовать pd.cut
.
Вау, большое спасибо, я не знаю, что функция searchsorted() может это сделать. А для категориального, я думаю, мне потребовалось несколько часов, чтобы преобразовать его в тип списка -_-
qcut
для квантили. Если у вас уже есть точки среза, вы, вероятно, захотитеpd.cut