Поворот фрейма данных при дублировании индексов

Какой код Python переведет меня из исходного фрейма данных в окончательный фрейм данных? Я изо всех сил пытаюсь найти какие-либо функции pandas для этого типа поворота.

Исходный фрейм данных:

    test1  test2 class value1
0       1      5  type  type1
1       1      5  type  type3
2       2      6  type  type1
3       3      7  type  type2
4       1      5   lat     40
5       1      5   lat     20
6       2      6   lat     50
7       3      7   lat     60
8       1      5   lon      1
9       1      5   lon      2
10      2      6   lon      2
11      3      7   lon      3

Окончательный фрейм данных:

   test1  test2   type  lat  lon
0      1      5  type1   40    1
1      2      6  type1   50    2
2      3      7  type2   60    3
3      1      5  type3   20    2 

Я устал использовать сводную функцию pandas, но получаю следующую ошибку.

df_pivoted = df_orig.pivot(
    index=['test1', 'test2'],
    columns='class',
    values='value1')
ValueError: Index contains duplicate entries, cannot reshape
Почему в 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 может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
0
54
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Дедуплицируйте строки перед pivot:

cols = ['test1', 'test2']
out = (
 df.assign(n=df.groupby(cols+['class']).cumcount())
   .pivot(index=['n']+cols, columns='class', values='value1')
   .reset_index().rename_axis(columns=None).drop(columns='n')
)

Выход:

   test1  test2 lat lon   type
0      1      5  40   1  type1
1      2      6  50   2  type1
2      3      7  60   3  type2
3      1      5  20   2  type3

предыдущий ответ (до редактирования вопроса)

Это совсем не простой пивот , между test1/test2 и class/value нет прямой связи, вы должны обрабатывать обе части отдельно и join:

cols = ['test1', 'test2']

g = df_orig.groupby('class', sort=False)

out = (df_orig[cols]
       .assign(n=g.ngroup())
       .drop_duplicates('n').set_index('n')
       .join((df_orig.drop(columns=cols).assign(n=g.cumcount())
             .pivot(index='n', columns='class', values='value1')
              ))
       .reset_index(drop=True)
      )

print(out)

Выход:

   test1  test2 lat lon   type
0      1      5  40   1  type1
1      2      6  50   2  type1
2      3      7  60   3  type2

простой поворот

Для простого pivot ваш ввод должен выглядеть так:

   test1  test2 class value1
0      1      5  type  type1
1      2      6  type  type1
2      3      7  type  type2
3      1      5   lat     40
4      2      6   lat     50
5      3      7   lat     60
6      1      5   lon      1
7      2      6   lon      2
8      3      7   lon      3

И вы можете использовать:

df.pivot(index=['test1', 'test2'], columns='class', values='value1').reset_index()

Извините... Я сделал обновление, проблема заключалась в дублировании столбцов индекса.

Adam J. Berlier 31.03.2023 21:21

FWIW, если вы хотите, чтобы столбцы были в том же порядке, что и ввод, вы можете поместить это перед .reset_index(): .reindex(df['class'].unique(), axis=1).

wjandrea 31.03.2023 22:57

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