Есть два DF:
df_estim = pd.DataFrame({'estim': ['est1', 'est2', 'est3'],
'title': ['title1', 'title2', 'title3'],
'key': ['key1', 'key2', 'key3'],
'mount': [300.15, 350.85, 400.47],
'equip': [870.35, 1750.59, 1830.80]})
df_estim
estim title key mount equip
0 est1 title1 key1 300.15 870.35
1 est2 title2 key2 350.85 1750.59
2 est3 title3 key3 400.47 1830.80
df_equip = pd.DataFrame({'sys_2': ['sys1', 'sys1', 'sys1', 'sys1', 'sys1', 'sys1',
'sys2', 'sys2', 'sys2', 'sys2',
'sys2', 'sys2', 'sys2', 'sys2', 'sys3', 'sys3',
'sys3', 'sys3', 'sys3', 'sys3',
'sys3', 'sys3'],
'block_2': [0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
1, 2, 2, 2, 0, 0, 0, 1, 1, 2,
2, 2],
'kks_2': ['kks1', 'kks2', 'kks3', 'kks4', 'kks5', 'kks6', 'kks7',
'kks8', 'kks9', 'kks10',
'kks11', 'kks12', 'kks13', 'kks14', 'kks15', 'kks16',
'kks17', 'kks18', 'kks19', 'kks20',
'kks21', 'kks22'],
'key': ['key1', 'key1', 'key2', 'key2', 'key3', 'key3', 'key1',
'key1', 'key2', 'key3',
'key3', 'key2', 'key1', 'key1', 'key2', 'key2', 'key3',
'key2', 'key3', 'key2',
'key3', 'key3'],
'price_2': [100.10, 110.10, 120.10, 130.10, 140.10, 150.10, 160.10,
170.10, 180.10, 190.10,
200.10, 210.10, 220.10, 230.10, 240.10, 250.10, 260.10,
270.10, 280.10, 290.10,
300.10, 310.10]
})
df_equip[:5]
sys_2 block_2 kks_2 key price_2
0 sys1 0 kks1 key1 100.1
1 sys1 0 kks2 key1 110.1
2 sys1 0 kks3 key2 120.1
3 sys1 0 kks4 key2 130.1
4 sys1 0 kks5 key3 140.1
Для дальнейшего объяснения делаю объединение:
merge_df = pd.merge(df_equip, df_estim, how='inner', left_on='key', right_on='key',
left_index=False)
merge_df[:5]
sys_2 block_2 kks_2 key price_2 estim title mount equip
0 sys1 0 kks1 key1 100.1 est1 title1 300.15 870.35
1 sys1 0 kks2 key1 110.1 est1 title1 300.15 870.35
2 sys2 1 kks7 key1 160.1 est1 title1 300.15 870.35
3 sys2 1 kks8 key1 170.1 est1 title1 300.15 870.35
4 sys2 2 kks13 key1 220.1 est1 title1 300.15 870.35
Нужно из полученных вспомогательных данных (ниже):
merge_df.groupby(['estim', 'equip'])['price_2'].sum()
estim equip
est1 870.35 990.6
est2 1750.59 1690.8
est_3 1830.80 1830.8
вычислить отношение по каждой записи estim между данными колонки equip и ['price_2'].sum(),
и поместить их в колонку coeff (например, для est1: 870.35/990.6 = 0.8786). Коэффициент
необходим для расчета данных в новой колонке estim_sys. Порядок расчета для est1: сумма
['price_2'].sum() / коэффициент для est1 = 0.8786. Итого: 239.24:
merge_df.groupby(['sys_2', 'block_2', 'estim'])['price_2'].sum()
sys_2 block_2 estim estim_sys
sys1 0 est1 239.24 210.2
est2 250.2
est3 290.2
sys2 1 est1 330.2
est2 180.1
est3 390.2
2 est1 450.2
est2 210.1
sys3 0 est2 490.2
est3 260.1
1 est2 270.1
est3 280.1
2 est2 290.1
est3 610.2
И еще прошу подсказать, как сохранить результаты (['price_2'].sum()) в стационарную
колонку, например cost_equip, что бы к ней можно было обращаться.
Ответы
Ответ 1
Попробуйте так:
m = merge_df.copy()
m["coeff"] = m["equip"] / m.groupby(['estim', 'equip'])['price_2'].transform("sum")
res = (m
.groupby(['sys_2', 'block_2', 'estim'])
.apply(lambda x: x["price_2"].sum() / x["coeff"])
.reset_index(name="estim_sys"))
In [32]: res
Out[32]:
sys_2 block_2 estim level_3 estim_sys
0 sys1 0 est1 0 239.241822
1 sys1 0 est1 1 239.241822
2 sys1 0 est2 6 241.654619
3 sys1 0 est2 7 241.654619
4 sys1 0 est3 14 290.200000
5 sys1 0 est3 15 290.200000
6 sys2 1 est1 2 375.821359
7 sys2 1 est1 3 375.821359
8 sys2 1 est2 8 173.948829
9 sys2 1 est3 16 390.200000
10 sys2 1 est3 17 390.200000
11 sys2 2 est1 4 512.400896
12 sys2 2 est1 5 512.400896
13 sys2 2 est2 9 202.924203
14 sys3 0 est2 10 473.457611
15 sys3 0 est2 11 473.457611
16 sys3 0 est3 18 260.100000
17 sys3 1 est2 12 260.874951
18 sys3 1 est3 19 280.100000
19 sys3 2 est2 13 280.191867
20 sys3 2 est3 20 610.200000
21 sys3 2 est3 21 610.200000
Как образовалась колонка "level_3"?
в столбце level_3 - значения оригинального индекса из merge_df DataFrame.
Как правильно добавить колонку "estim_sys" из "res" в "m"?
здесь мы как раз можем использовать столбец "level_3", чтобы Pandas смог выровнять
данные по индексам при присваивании:
In [42]: m["estim_sys"] = res.set_index("level_3")["estim_sys"]
In [43]: m
Out[43]:
sys_2 block_2 kks_2 key price_2 ... title mount equip coeff
estim_sys
0 sys1 0 kks1 key1 100.1 ... title1 300.15 870.35 0.878609
239.241822
1 sys1 0 kks2 key1 110.1 ... title1 300.15 870.35 0.878609
239.241822
2 sys2 1 kks7 key1 160.1 ... title1 300.15 870.35 0.878609
375.821359
3 sys2 1 kks8 key1 170.1 ... title1 300.15 870.35 0.878609
375.821359
4 sys2 2 kks13 key1 220.1 ... title1 300.15 870.35 0.878609
512.400896
5 sys2 2 kks14 key1 230.1 ... title1 300.15 870.35 0.878609
512.400896
6 sys1 0 kks3 key2 120.1 ... title2 350.85 1750.59 1.035362
241.654619
7 sys1 0 kks4 key2 130.1 ... title2 350.85 1750.59 1.035362
241.654619
8 sys2 1 kks9 key2 180.1 ... title2 350.85 1750.59 1.035362
173.948829
9 sys2 2 kks12 key2 210.1 ... title2 350.85 1750.59 1.035362
202.924203
10 sys3 0 kks15 key2 240.1 ... title2 350.85 1750.59 1.035362
473.457611
11 sys3 0 kks16 key2 250.1 ... title2 350.85 1750.59 1.035362
473.457611
12 sys3 1 kks18 key2 270.1 ... title2 350.85 1750.59 1.035362
260.874951
13 sys3 2 kks20 key2 290.1 ... title2 350.85 1750.59 1.035362
280.191867
14 sys1 0 kks5 key3 140.1 ... title3 400.47 1830.80 1.000000
290.200000
15 sys1 0 kks6 key3 150.1 ... title3 400.47 1830.80 1.000000
290.200000
16 sys2 1 kks10 key3 190.1 ... title3 400.47 1830.80 1.000000
390.200000
17 sys2 1 kks11 key3 200.1 ... title3 400.47 1830.80 1.000000
390.200000
18 sys3 0 kks17 key3 260.1 ... title3 400.47 1830.80 1.000000
260.100000
19 sys3 1 kks19 key3 280.1 ... title3 400.47 1830.80 1.000000
280.100000
20 sys3 2 kks21 key3 300.1 ... title3 400.47 1830.80 1.000000
610.200000
21 sys3 2 kks22 key3 310.1 ... title3 400.47 1830.80 1.000000
610.200000
[22 rows x 11 columns]