interval_range и pd.cut с игнорированием Overlapping error
Имеется код, который делит датафрейм на сегменты(колонка n1) в зависимости от колонки linear.
import pandas as pd
import numpy as np
d = {'stores': ['AG21', 'AG41', 'AG85', 'AG45',
'AG31', 'AS25', 'AR81', 'AA43',
'AG21', 'AD83', 'AA36', 'AG55',
'AT58', 'AD11', 'AH32', 'AE17'],
'linear': [430, 145 , 120, 180,
250, 250, 250, 320,
376, 390, 420, 580,
350, 190, 125, 390]}
df = pd.DataFrame(data=d)
df = df.sort_values(by='linear')
ints = pd.interval_range(start=df['linear'].min(), periods=6, end=df['linear'].max(), closed='left')
df['ranges'] = pd.cut(df['linear'], bins=ints,labels=False, include_lowest=True)
def fun(x):
if isinstance(x, float) is True:
return np.nan
else:
return x.right
df['ranges1'] = df['ranges'].apply(fun)
df['n1'] = (df['ranges1'] != df['ranges1'].shift()).cumsum()
df
При попытке указания closed='both' в interval_range, для отображения нижней и верхней границы в расчете, получаю ошибку:
ValueError: Overlapping IntervalIndex is not accepted.
Нужно так, чтобы последняя строчка в linear тоже учитывалась в диапазоне, а closed='left' не берет ее.
Ответы (1 шт):
Автор решения: CrazyElf
→ Ссылка
Подозреваю, что проблема в точности представления чисел с плавающей точкой. Ну и в том, что у вас числа прямо на границе интервалов. Как это красиво/правильно вылечить не знаю, но если добавить некий эпсилон к правому краю в pd.interval_range, то последнее значение попадёт в интервал:
end = df['linear'].max() + 1e-12
Вывод:
...
0 AG21 430 [426.66666666666737, 503.3333333333342) 503.333333 5
11 AG55 580 [503.3333333333342, 580.000000000001) 580.000000 6