Возвращает ряд числовых позиций для индексов, представляющих максимум в каждой группе

Рассмотрим ряд:

np.random.seed([3,1415])
s = pd.Series(np.random.rand(100),
              pd.MultiIndex.from_product([list('ABDCE'),
                                          list('abcde'),
                                          ['One', 'Two', 'Three', 'Four']]))

Я могу groupby сочетания уровней индекса и получить idxmax:

s.groupby(level=[0, 2]).idxmax()

A  Four      (A, c, Four)
   One        (A, d, One)
   Three    (A, c, Three)
   Two        (A, d, Two)
B  Four      (B, d, Four)
   One        (B, d, One)
   Three    (B, c, Three)
   Two        (B, b, Two)
C  Four      (C, b, Four)
   One        (C, a, One)
   Three    (C, a, Three)
   Two        (C, e, Two)
D  Four      (D, b, Four)
   One        (D, e, One)
   Three    (D, b, Three)
   Two        (D, c, Two)
E  Four      (E, c, Four)
   One        (E, a, One)
   Three    (E, c, Three)
   Two        (E, a, Two)
dtype: object

Мне нужна числовая позиция каждой из этих внутри каждой группы.

Я могу получить числовые позиции с помощью удивительных ответов на этот вопрос

s.groupby(level=[0, 2]).idxmax().apply(lambda x: s.index.get_loc(x))

A  Four     11
   One      12
   Three    10
   Two      13
B  Four     35
   One      32
   Three    30
   Two      25
C  Four     67
   One      60
   Three    62
   Two      77
D  Four     47
   One      56
   Three    46
   Two      49
E  Four     91
   One      80
   Three    90
   Two      81
dtype: int64

Но я хочу это вместо:

A  Four     2
   One      3
   Three    2
   Two      3
B  Four     3
   One      3
   Three    2
   Two      1
C  Four     1
   One      0
   Three    0
   Two      4
D  Four     1
   One      4
   Three    1
   Two      2
E  Four     2
   One      0
   Three    2
   Two      0
dtype: int64

Ответы

Ответ 1

Ну, наконец, у меня есть решение, которое использует метод изменения NumPy, а затем работает по одной из осей, чтобы дать нам argmax. Я не уверен, что это элегантно, но я надеюсь, что это будет хорошо с точки зрения производительности. Кроме того, я предполагаю, что pandas Series для данных с несколькими индексами имеет обычный формат, т.е. На каждом уровне поддерживается количество элементов по всем индексам.

Вот реализация -

  L0, L1, L2 = s.index.levels [: 3]
IDs = s.sortlevel(). Values.reshape(-1, len (L0), len (L1), len (L2)). Argmax (2)
sOut = pd.Series(IDs.ravel(), pd.MultiIndex.from_product ([L0, L2]))
Код>

Сроки (дополнения pir)

введите описание изображения здесь

Ответ 2

Вот как я это сделал:

s.groupby(level=[0, 2]).apply(lambda x: x.index.get_loc(x.idxmax()))

A  Four     2
   One      3
   Three    2
   Two      3
B  Four     3
   One      3
   Three    2
   Two      1
C  Four     1
   One      0
   Three    0
   Two      4
D  Four     1
   One      4
   Three    1
   Two      2
E  Four     2
   One      0
   Three    2
   Two      0
dtype: int64