Страницы

Поиск по вопросам

среда, 26 февраля 2020 г.

Вычисление данных в сгруппированном Data Frame

#python #python_3x #pandas #dataframe #group_by


Есть два 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]

Комментариев нет:

Отправить комментарий