Расчет показателя из двух DataFrame
Необходимо посчитать сумму потраченную каждым пользователем по месяцам за каждый вид услуг (сообщения и звонки) и суммарное количество средств, потраченных за месяц) информация по лимитам, которые входят в тариф представлена в df1, информация о самих пользователях в df2. Если количество сообщений или трафика больше чем входит в тариф, то считаем сколько за это заплатил пользователь, если не превысил лимит, то считаем что стоимость 0.
df1 = [[50, 4000, 3, 5, tarif1], [1000, 2000, 2, 4, tarif2]]
columns = ['messages_included', 'minutes_included','rub_per_message', 'rub_per_minute', 'tariff_name']
df2 = [[1, tarif1, 5, 20, 100], [1, tarif1, 6, 150, 250], [1, tarif1, 7, 100, 200], [2, tarif1, 5, 45, 10], [2, tarif1, 6, 100, 0], [3, tarif2, 5, 12, 98], [3, tarif2, 6, 10, 6000], [3, tarif2, 7, 800, 2000], [4, tarif2, 5, 80, 10], [4, tarif2, 6, 1000, 500]
columns = ['user_id', 'tariff', 'month', 'total_messages', 'calls_sum']
Предполагаемый результат, в df2 добавятся колонки, стоимость затраты за месяц на звонки и сообщения, и колонка с суммарными затратами сверх тарифа складывающаяся из стоимости сообщения и звонков.
columns = ['user_id', 'tariff', 'month', 'total_messages', 'calls_sum', 'messages_revenue', 'calls_revenue', 'total_revenue']
Итоговая таблица должна выглядеть вот так https://imgur.com/a/yvL3mgA
Ответы (2 шт):
Попробуйте так:
t = df2.reset_index().merge(df1.rename(columns={"tariff_name": "tariff"})).set_index("index")
t["messages_revenue"] = (t["total_messages"] - t["messages_included"]).clip(0) * t["rub_per_message"]
t["calls_revenue"] = (t["calls_sum"] - t["minutes_included"]).clip(0) * t["rub_per_minute"]
t["total_revenue"] = t["messages_revenue"] + t["calls_revenue"]
res = df2.join(t.filter(regex="revenue"))
результат:
In [69]: res
Out[69]:
user_id tariff month total_messages calls_sum messages_revenue calls_revenue total_revenue
0 1 tarif1 5 20 100 0 0 0
1 1 tarif1 6 150 250 300 0 300
2 1 tarif1 7 100 200 150 0 150
3 2 tarif1 5 45 10 0 0 0
4 2 tarif1 6 100 0 150 0 150
5 3 tarif2 5 12 98 0 0 0
6 3 tarif2 6 10 6000 0 16000 16000
7 3 tarif2 7 800 2000 0 0 0
8 4 tarif2 5 80 10 0 0 0
9 4 tarif2 6 1000 500 0 0 0
Альтернативное решение:
formulas = """
messages_revenue = (total_messages - messages_included) * rub_per_message
calls_revenue = (calls_sum - minutes_included) * rub_per_minute"""
t = (df2
.reset_index()
.merge(df1.rename(columns={"tariff_name": "tariff"}))
.set_index("index"))
res = (df2
.join(t.eval(formulas)
.filter(regex="\_revenue")
.clip(0)
.eval("total_revenue = messages_revenue + calls_revenue")))
результат:
In [81]: res
Out[81]:
user_id tariff month total_messages calls_sum messages_revenue calls_revenue total_revenue
0 1 tarif1 5 20 100 0 0 0
1 1 tarif1 6 150 250 300 0 300
2 1 tarif1 7 100 200 150 0 150
3 2 tarif1 5 45 10 0 0 0
4 2 tarif1 6 100 0 150 0 150
5 3 tarif2 5 12 98 0 0 0
6 3 tarif2 6 10 6000 0 16000 16000
7 3 tarif2 7 800 2000 0 0 0
8 4 tarif2 5 80 10 0 0 0
9 4 tarif2 6 1000 500 0 0 0
