Агрегированные значения мультииндексного деления pandas

Мои необработанные данные как таковые

    level0  level1  level2
0   0       A       foo
1   0       A       bar
2   0       B       foo
3   0       B       foo
4   0       B       foo
5   0       B       bar
6   1       A       foo
7   1       A       bar

И затем я пытаюсь сгруппировать счетчики как таковые df.groupby(['level0', 'level1', 'level2']).size()

чтобы получить это

level0  level1  level2
0       A       foo            1
                bar            1
        B       foo            3
                bar            1
1       A       foo            1
                bar            1
        B       foo            1
                bar            1
2       A       foo            1
                bar            1
        B       foo            1
                bar            1

А теперь мне бы просто хотелось разделить количество уровней level2 в соотношении bar/foo, чтобы получить что-то вроде этого:

level0  level1      {bar counts/foo counts}
0       A           1.00
        B           0.33
1       A           1.00
        B           1.00
2       A           1.00
        B           1.00

Возможно, я даже неправильно настроил исходную группу, но также попробовал .div, .apply и т. д., но у меня возник ментальный блок. Спасибо за любое руководство!

2
0
51
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Код

# your groupby code
tmp = df.groupby(['level0', 'level1', 'level2']).size() 

# get desired output by xs and div
out = tmp.xs('bar', level=2).div(tmp.xs('foo', level=2))

вне:

level0  level1
0       A         1.000000
        B         0.333333
1       A         1.000000
Ответ принят как подходящий

unstack и eval:

tmp = df.groupby(['level0', 'level1', 'level2']).size()

out = (tmp.unstack().eval('bar/foo')
          .reset_index(name='bar/foo')
      )

Или div:

tmp = (df.groupby(['level0', 'level1', 'level2'])
         .size().unstack()
      )

out = (tmp['bar']
       .div(tmp['foo'])
       .reset_index(name='bar/foo')
      )

Выход:

   level0 level1   bar/foo
0       0      A  1.000000
1       0      B  0.333333
2       1      A  1.000000

@Скотт, морж не нужен, out = df.groupby(['level0', 'level1', 'level2']).size().unstack().eval('bar/foo') достаточно. Я просто разделил его на две части, так как это был оригинальный код ОП;)

mozway 24.02.2024 23:18

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