Создайте новый фрейм данных из совокупности исходных df и вычислений

Я хочу создать новый фрейм данных из моего исходного фрейма данных, который объединяется по двум столбцам и имеет вычисляемый столбец, зависящий от суммы выбранных строк из двух других столбцов.

Вот пример df:

df = pd.DataFrame([['A','X',2000,5,3],['A','X',2001,6,2],['B','X',2000,6,3],['B','X',2001,7,2],['C','Y',2000,10,4],['C','Y',2001,12,4],['D','Y',2000,11,2],['D','Y',2001,15,1]],
                   columns=['ctry','rgn','year','val1, val2']))

и как это выглядит:

   ctry rgn  year  val1  val2
0     A   X  2000     5     3
1     A   X  2001     6     2
2     B   X  2000     6     3
3     B   X  2001     7     2
4     C   Y  2000     10    4
5     C   Y  2001     12    4
6     D   Y  2000     11    2
7     D   Y  2001     15    1

В конечном итоге мне нужен новый фрейм данных, который избавится от столбца ctry и группируется по rgn и year и имеет вычисляемый столбец value, зависящий от val1 и val2, такой, что сумма произведения val1 и val2 делится на сумму val2 для rgn и year:

df['value'] = ∑(val1*val2)/∑val2 для каждого года и года

   rgn  year  value
0    X  2000  5.5
1    X  2001  6.5
2    Y  2000  10.333333
3    Y  2001  12.6

В итоге я успешно сделал это:

df['calc'] = df['val1'] * df['val2']
new_df = df.groupby(['rgn', 'year']).sum()
new_df['value'] = new_df['calc']/new_df['val2']
new_df = new_df.reset_index().rename_axis(None, axis=1)
new_df = new_df.drop(columns=['ctry', 'val1', 'val2', 'calc'])

Однако я хотел бы знать, есть ли более краткий способ, не требующий всех этих шагов, возможно, с использованием лямбда-функции. Ценю любую помощь, которую я получаю. Спасибо!

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
4
0
65
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Предварительно вычислите value = val1*val2, выполните groupby.sum, затем вычислите value/val1:

out = (df.eval('value = val1*val2')
         .groupby(['rgn', 'year'], as_index=False)
         [['value', 'val2']].sum()
         .assign(value=lambda x: x['value']/x.pop('val2'))
      )

Менее эффективно, но более гибко вы также можете использовать groupby.apply:

out = (df.groupby(['rgn', 'year'])
         .apply(lambda x: (x['val1']*x['val2']).sum()/x['val2'].sum(),
                include_groups=False)
         .reset_index(name='value')
      )

Выход:

  rgn  year      value
0   X  2000   5.500000
1   X  2001   6.500000
2   Y  2000  10.333333
3   Y  2001  12.600000

Другие вопросы по теме