Как правильно подсчитать количество минут поверх заданного тарифа - pandas
Подскажите, пожалуйста, как можно подсчитать правильно количество минут поверх заданного тарифа и записать результат в один столбец?
Задача следующая : есть таблица с данными по количеству клиентов в телеком компании, а также их тарифами и количеством минут, которые операторы тратили за конкретный месяц. Необходимо просчитать количество исходящих минут по внутренним звонкам и сравнить, был ли превышен лимит у того или иного клиента. У меня сложность встала в том, что я логически понимаю как подсчитать всё это, но вот как выстроить условия для трех разных тарифов и записать всю в один столбец - тупняк полный. Помогите разобраться, пожалуйста.
Таблица, в которую планирую добавлять данные по следующим критериям
Пример моего кода:
internal_over_limit = ((df_revenue_month['direction']=='out') &
(df_revenue_month['internal']==True) &
(df_revenue_month['tariff_plan']=='C') &
(df_revenue_month['total_minutes']>0))
df_revenue_month.loc[internal_over_limit, 'minutes_internal_over_limit'] = df_revenue_month['total_minutes'] - 0
df_revenue_month['minutes_internal_over_limit'] = df_revenue_month['minutes_internal_over_limit'].fillna(0)
df_revenue_month.head(5)
Глобально - он выполняет мою цель, но лишь частично. У каждого тарифного плана свой лимит, который нужно отсчитывать и выводить в новый столбец данные ТОЛЬКО поверх лимита. А - 2000, B - 500, С - 0.
Направьте, пожалуйста. Заранее спасибо!
Ответы (1 шт):
Описание вопроса неполное - нет воспроизводимого фрагмента исходных данных и отсутствует образец ожидаемого результата, который должен получаться после обработки данных. Сделал, как понял. Может, угадал, а может, и нет.
По сути решения. Сначала нужно отфильтровать фрейм df = df[df.direction.eq('out') & df.internal]. Далее группируем по id и plan и применяем transform(sum), суммируя все минуты по каждой группе. После чего отнимаем Series c плановыми минутами, полученный путем замены букв плана на плановые лимиты, заданные в словаре limits. Результат обрабатываем методом mask, заменяя отрицательные числа на 0.
df = pd.DataFrame({'id': [123] * 3 + [456] * 3, 'plan': ['B'] * 3 + ['A'] * 3, 'direction': ['in', 'out'] * 3, 'internal': [False, True] * 3, 'minutes': [200, 300, 400, 100, 200, 3000]})
limits = {'A': 2000, 'B': 500, 'C': 0}
print(df)
df = df[df.direction.eq('out') & df.internal]
df['over'] = (df.groupby(['id', 'plan']).minutes.transform(sum) - df.plan.replace(limits)).mask(lambda x: x < 0, 0)
print(df)
id plan direction internal minutes
0 123 B in False 200
1 123 B out True 300
2 123 B in False 400
3 456 A out True 100
4 456 A in False 200
5 456 A out True 3000
id plan direction internal minutes over
1 123 B out True 300 0
3 456 A out True 100 1100
5 456 A out True 3000 1100
