Преобразование фрейма данных Pandas в pandas с несколькими столбцами

#python #pandas #dataframe #multi-index

#python #pandas #фрейм данных #многоиндексный

Вопрос:

У меня есть следующий фрейм данных pandas, где столбец id является индексом фрейма данных

  ---- ----------- ------------ ----------- ------------ 
|    |   price_A |   amount_A |   price_B |   amount_b |
|---- ----------- ------------ ----------- ------------|
|  0 | 0.652826  |  0.941421  |  0.823048 |  0.728427  |
|  1 | 0.400078  |  0.600585  |  0.194912 |  0.269842  |
|  2 | 0.223524  |  0.146675  |  0.375459 |  0.177165  |
|  3 | 0.330626  |  0.214981  |  0.389855 |  0.541666  |
|  4 | 0.578132  |  0.30478   |  0.789573 |  0.268851  |
|  5 | 0.0943601 |  0.514878  |  0.419333 |  0.0170096 |
|  6 | 0.279122  |  0.401132  |  0.722363 |  0.337094  |
|  7 | 0.444977  |  0.333254  |  0.643878 |  0.371528  |
|  8 | 0.724673  |  0.0632807 |  0.345225 |  0.935403  |
|  9 | 0.905482  |  0.8465    |  0.585653 |  0.364495  |
 ---- ----------- ------------ ----------- ------------ 

 

И я хочу преобразовать этот фрейм данных в многоколоночный фрейм данных, который выглядит следующим образом

 
 ---- ----------- ------------ ----------- ------------ 
|    |           A            |           B            |
 ---- ----------- ------------ ----------- ------------ 
| id |   price   |   amount   |   price   |   amount   |
|---- ----------- ------------ ----------- ------------|
|  0 | 0.652826  |  0.941421  |  0.823048 |  0.728427  |
|  1 | 0.400078  |  0.600585  |  0.194912 |  0.269842  |
|  2 | 0.223524  |  0.146675  |  0.375459 |  0.177165  |
|  3 | 0.330626  |  0.214981  |  0.389855 |  0.541666  |
|  4 | 0.578132  |  0.30478   |  0.789573 |  0.268851  |
|  5 | 0.0943601 |  0.514878  |  0.419333 |  0.0170096 |
|  6 | 0.279122  |  0.401132  |  0.722363 |  0.337094  |
|  7 | 0.444977  |  0.333254  |  0.643878 |  0.371528  |
|  8 | 0.724673  |  0.0632807 |  0.345225 |  0.935403  |
|  9 | 0.905482  |  0.8465    |  0.585653 |  0.364495  |
 ---- ----------- ------------ ----------- ------------ 

 

Я попытался преобразовать свой старый фрейм данных pandas в dict таким образом:

    dict = {"A": df[["price_a","amount_a"]], "B":df[["price_b", "amount_b"]]}
   df = pd.DataFrame(dict, index=df.index)

 

Но у меня не было успеха, как я могу это сделать?

Ответ №1:

Попробуйте переименовать столбцы вручную:

 df.columns=pd.MultiIndex.from_tuples([x.split('_')[::-1] for x in df.columns])
df.index.name='id'
 

Вывод:

            A                   B         b
       price    amount     price    amount
id                                        
0   0.652826  0.941421  0.823048  0.728427
1   0.400078  0.600585  0.194912  0.269842
2   0.223524  0.146675  0.375459  0.177165
3   0.330626  0.214981  0.389855  0.541666
4   0.578132  0.304780  0.789573  0.268851
5   0.094360  0.514878  0.419333  0.017010
6   0.279122  0.401132  0.722363  0.337094
7   0.444977  0.333254  0.643878  0.371528
8   0.724673  0.063281  0.345225  0.935403
9   0.905482  0.846500  0.585653  0.364495
 

Ответ №2:

Вы можете разделить имена столбцов на подчеркивание и преобразовать в кортеж. Как только вы сопоставите каждое разделенное имя столбца с кортежем, pandas преобразует Index его в a MultiIndex для вас. Оттуда нам просто нужно вызвать swaplevel , чтобы уровень букв был первым и переназначен фрейму данных.

примечание: в моем входном фрейме данных я заменил имя столбца «amount_b» на «amount_B», потому что оно соответствовало вашему ожидаемому результату, поэтому я предположил, что это опечатка

 df.columns = df.columns.str.split("_", expand=True).swaplevel()

print(df)
          A                   B
      price    amount     price    amount
0  0.652826  0.941421  0.823048  0.728427
1  0.400078  0.600585  0.194912  0.269842
2  0.223524  0.146675  0.375459  0.177165
3  0.330626  0.214981  0.389855  0.541666
4  0.578132  0.304780  0.789573  0.268851
5  0.094360  0.514878  0.419333  0.017010
6  0.279122  0.401132  0.722363  0.337094
7  0.444977  0.333254  0.643878  0.371528
8  0.724673  0.063281  0.345225  0.935403
9  0.905482  0.846500  0.585653  0.364495
 

Комментарии:

1. Вы можете пропустить map(tuple) часть с expand=True помощью; он преобразует столбцы в мультииндекс: df.columns.str.split("_", expand=True).swaplevel()

2. Спасибо за предложение! Я полностью забыл об expand аргументе, и я не знал, что это приведет Index к a MultiIndex . Отличный трюк, который нужно знать 🙂

3. Спасибо! Это решение также работает.