Выборочно используйте df.div () для разделения только определенного столбца на основе совпадения индекса - PullRequest
0 голосов
/ 08 апреля 2020

У меня есть 2 DataFrames, один из которых является месячным итогом, а другой содержит значения, на которые я хочу разделить первое, чтобы получать ежемесячные процентные взносы.

Вот несколько примеров DataFrames:

MonthlyTotals = pd.DataFrame(data={'Month':[1,2,3],'Value':[100,200,300]})

Data = pd.DataFrame(data={'ID':[1,2,3,1,2,3,1,2,3],
                          'Month':[1,1,1,2,2,2,3,3,3],
                          'Value':[40,30,30,60,70,70,150,60,90]})

Я использую df.div(), поэтому я устанавливаю индекс следующим образом

MonthlyTotals.set_index('Month', inplace=True)
Data.set_index('Month', inplace=True)

Затем делаю

Contributions = Data.div(MonthlyTotals, axis='index')

Полученный DataFrame - это то, что я хочу, но я не может видеть ID, к которому относится Value, поскольку его нет в кадре MonthlyTotals. Как бы я использовал df.div(), но только выборочно для определенных столбцов?

Вот примерный кадр данных результата, который я ищу

result = pd.DataFrame(data={'ID':[1,2,3,1,2,3,1,2,3],'Value':[0.4,0.3,0.3,0.3,0.35,0.35,0.5,0.2,0.3]})

Ответы [ 2 ]

2 голосов
/ 08 апреля 2020

Вам могут не понадобиться месячные итоги, если данные заполнены. Вы можете рассчитать MonthlyTotal, используя transform, а затем рассчитать взносы.

Data = pd.DataFrame(data={'ID':[1,2,3,1,2,3,1,2,3],
                          'Month':[1,1,1,2,2,2,3,3,3],
                          'Value':[40,30,30,60,70,70,150,60,90]})
Data['MonthlyTotal'] = Data.Gropuby('Month')['Value'].transform('sum')
Data['Contributions'] = Data['Value'] / Data['MonthlyTotal']

Вывод

   ID  Month  Value  MonthlyTotal  Contributions
0   1      1     40           100           0.40
1   2      1     30           100           0.30
2   3      1     30           100           0.30
3   1      2     60           200           0.30
4   2      2     70           200           0.35
5   3      2     70           200           0.35
6   1      3    150           300           0.50
7   2      3     60           300           0.20
8   3      3     90           300           0.30
1 голос
/ 08 апреля 2020

Также, если вы хотите использовать только pandas, вы можете исправить свой код с помощью reindex + update

Data.update(Data['Value'].div(MonthlyTotals['Value'].reindex(Data.index),axis=0))
Data
       ID  Value
Month           
1       1   0.40
1       2   0.30
1       3   0.30
2       1   0.30
2       2   0.35
2       3   0.35
3       1   0.50
3       2   0.20
3       3   0.30
...