Разделите данные на бины с помощью inf Python

У меня проблема с функцией 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))

person Long_NgV    schedule 29.05.2019    source источник
comment
qcut для квантили. Если у вас уже есть точки разреза, вам, вероятно, понадобится pd.cut   -  person piRSquared    schedule 29.05.2019


Ответы (2)


На самом деле вам нужен 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, не может быть отрицательного значения процентиля, и, следовательно, вы получаете ошибку.

person Mohit Motwani    schedule 29.05.2019
comment
Ах, так это проблема с -np.inf, так что 1e100 в этом случае не нужен, верно? Бв спасибо большое - person Long_NgV; 29.05.2019

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.

person piRSquared    schedule 29.05.2019
comment
Вау, большое спасибо, я не знаю, что функция searchsorted() может это сделать. А для категориального, я думаю, мне потребовалось несколько часов, чтобы преобразовать его в тип списка -_- - person Long_NgV; 29.05.2019