Как преобразовать обычный фрейм данных в MultiIndex в зависимости от определенных условий - PullRequest
2 голосов
/ 15 апреля 2020

После долгого времени, пока я заходил в раздел pandas SO и получил вопрос, который на самом деле не очень красиво сформулирован, поэтому я решил поставить здесь в явном виде ситуацию подобного рода, что я тоже тоже: -)

Ниже приведена конструкция фрейма данных:

>>> df
       measure      Pend Job       Run Job       Time
cls
ABC  [inter, batch]     [101, 93]   [302, 1327]  [56, 131]
DEF  [inter, batch]  [24279, 421]  [4935, 5452]  [75, 300]

Желаемый результат будет ...

Я старался изо всех сил, но не нашел никакого решения, таким образом, хотя Sketch это здесь, так как это несколько, я хотел бы, чтобы это было достигнуто.

----------------------------------------------------------------------------------
    |                 |Pend Job     |       Run Job       |     Time             |
cls | measure         |-----------------------------------------------------------
    |                 |inter | batch|       |inter | batch|     |inter | batch   |
----|-----------------|------|------|-------|------|------|-----|------|----------                    
ABC |inter, batch     |101   |93    |       |302   |1327  |     |56    |131      |
----|-----------------|-------------|-------|------|------|-----|------|---------|
DEF |inter, batch     |24279 |421   |       |4935  |5452  |     |75    |300      |
----------------------------------------------------------------------------------

Сказав, что я хочу, чтобы мой dataFrame переместился в MultiIndex Dataframe, где Pend Job, Run Job и Time должны быть сверху, как указано выше .

Спасибо за любое экспертное решение, будьте в безопасности и здоровы.

Редактировать:

cls нет в столбцах

1 Ответ

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

Это мой подход, вы можете изменить его по своему усмотрению:

s = (df.drop('measure', axis=1)                   # remove the measure column
       .set_index(df['measure'].apply(', '.join), 
                  append=True)                    # make `measure` second level index
       .stack().explode().to_frame()              # concatenate all the values
    )

# assign `inter` and `batch` label to each new cell
new_lvl = np.array(['inter','batch'])[s.groupby(level=(0,1,2)).cumcount()]
# or
# new_lvl = np.tile(['inter', 'batch'], len(s)//2)

(s.set_index(new_level, append=True)[0]
  .unstack(level=(-2,-1)
  .reset_index()
)

Вывод:

   cls       measure Pend Job      
                        inter batch
0  ABC  inter, batch      101    93
1  DEF  inter, batch    24279   421
...