Переключение столбцов и строк в фрейме данных

У меня есть фрейм данных pandas, и мне нужно «переключить» строку и столбцы. (транспонировать? поворачивать? плавить? понятия не имею, как это называется):

Допустим, у меня есть 2 ссылки, каждая ссылка имеет 4 шага, каждый шаг имеет 3 переменные.

df = pd.DataFrame({'ref': ['ref1', 'ref1', 'ref1', 'ref1', 'ref2', 'ref2', 'ref2', 'ref2'],
                   'step': [1, 2, 3, 4, 1, 2, 3, 4],
                   'var_1': [5, 7, 7, 9, 12, 9, 87, 90],
                   'var_2': [11, 8, 10, 6, 6, 9, 12, 9],
                   "var_3": [11, 8, 10, 6, 6, 9, 12, 9]})



Я хочу преобразовать этот df в эту форму:

df = pd.DataFrame({'ref': ['ref1', 'ref2'],
>                    'step 1 - var_1': [5, 12],
>                    'step 1 - var_2': [11, 6],
>                    'step 1 - var_3': [11, 6],
>                    'step 2 - var_1': [7, 12],
>                    'step 2 - var_2': [8, 9],
>                    'step 2 - var_3': [8, 9]})




На df ниже я пробовал методы (и они работали):

(df
.pivot_wider(
    index='ref', 
    names_from='step',  
    values_from = ['var_1', 'var_2', 'var_3'],
    names_glue = "step {step} - {_value}")
.sort_index(axis=1)
) 

# and also
df_out = df.pivot(index='ref', columns='step').sort_index(level=1, axis=1)
df_out.columns = [f'step {j} - {i}' for i, j in df_out.columns]

Фактический df выглядит так:

Но они не работают с моим фактическим df, у меня есть код ошибки: «ValueError: индекс содержит повторяющиеся записи, не может изменить форму»

Последнее редактирование: у «уникального идентификатора» моего df был дубликат, теперь он работает, спасибо всем за ваш ответ. Сегодня узнал много нового :)

Заранее спасибо, Лучший

Редактировать: формат и изображения

Как вход соотносится с выходом?

BrokenBenchmark 10.01.2023 17:29

Судя по выходным столбцам, вы можете захотеть df.explode('step'), а затем rename(), но значения строк этому не соответствуют.

filpa 10.01.2023 17:40
Потяните за рычаг выброса энергососущих проектов
Потяните за рычаг выброса энергососущих проектов
На этой неделе моя команда отменила проект, над которым я работал. Неделя усилий пошла насмарку.
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Веб-скрейпинг, как мы все знаем, это дисциплина, которая развивается с течением времени. Появляются все более сложные средства борьбы с ботами, а...
Библиотека для работы с мороженым
Библиотека для работы с мороженым
Лично я попрощался с операторами print() в python. Без шуток.
Эмиссия счетов-фактур с помощью Telegram - Python RPA (BotCity)
Эмиссия счетов-фактур с помощью Telegram - Python RPA (BotCity)
Привет, люди RPA, это снова я и я несу подарки! В очередном моем приключении о том, как создавать ботов для облегчения рутины. Вот, думаю, стоит...
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Шаг 1: Создание приложения Slack Чтобы создать Slackbot, вам необходимо создать приложение Slack. Войдите в свою учетную запись Slack и перейдите на...
Учебник по веб-скрапингу
Учебник по веб-скрапингу
Привет, ребята... В этот раз мы поговорим о веб-скрейпинге. Целью этого обсуждения будет узнать и понять, что такое веб-скрейпинг, а также узнать, как...
2
2
78
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Использовать:

df[df.step<3].set_index(['ref','step']).unstack()

Выход:

     var_1    var_2    var_3   
step     1  2     1  2     1  2
ref                            
ref1     5  7    11  8    11  8
ref2    12  9     6  9     6  9

Это хороший подход, но необходимо изменить заголовки столбцов, чтобы они соответствовали запросу OP.

SNygard 10.01.2023 17:46

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

(df_new := df.set_index(['ref', 'step']).unstack().sort_index(level=1, axis=1))\
    .set_axis([f'step {j} - {i}' for i, j in df_new.columns], axis=1)

Выход:

      step 1 - var_1  step 1 - var_2  step 1 - var_3  step 2 - var_1  step 2 - var_2  step 2 - var_3  step 3 - var_1  step 3 - var_2  step 3 - var_3  step 4 - var_1  step 4 - var_2  step 4 - var_3
ref                                                                                                                                                                                                 
ref1               5              11              11               7               8               8               7              10              10               9               6               6
ref2              12               6               6               9               9               9              87              12              12              90               9               9

Подробности:

  • set_index со столбцами ref и step
  • unstack шаг для перехода в столбцы
  • Заказать вам колонки uinsg sort_index
  • сгладить заголовки столбцов мультииндексного фрейма данных, используя set_axis и список понимание с форматированием f-строки

Альтернативный способ с тем же выходом, что и выше,

df_out = df.pivot(index='ref', columns='step').sort_index(level=1, axis=1)
df_out.columns = [f'step {j} - {i}' for i, j in df_out.columns]

Привет, спасибо за ваш ответ, у меня есть эта ошибка, когда я запускаю код: «Индекс содержит повторяющиеся записи, не может изменить форму», знаете ли вы, почему?

chris_olv 11.01.2023 10:36

Да, у вас есть несколько записей с ref и step, вам нужно будет сделать groupby или pivot_table с каким-то агрегированием для обработки нескольких записей.

Scott Boston 11.01.2023 14:36

Хитрость заключается в использовании df.pivot. Вы можете выбрать index='ref' и columns='step':

new = df.pivot(index='ref', columns='step')

Полученная таблица имеет мультииндекс для ref и несколько столбцов. В мультистолбце есть информация о шаге и переменной, поэтому мы можем использовать ее для создания новых заголовков столбцов. Наконец, мы можем сбросить индекс:

new.columns = [f'step {x[1]} - {x[0]}' for x in new.columns]
new = new.reset_index()

Привет, SNygard, я попробовал ваш метод, но у меня есть код ошибки: «ValueError: индекс содержит повторяющиеся записи, не может изменить форму». Я отредактировал свой вопрос с подробностями, если это может помочь :)

chris_olv 11.01.2023 11:18
Ответ принят как подходящий

Один из вариантов — pivot_wider из pyjnanitor, чтобы абстрагироваться от переименования столбца с помощью параметра names_glue:

# pip insall pyjanitor
import pandas as pd
import janitor
(df
.pivot_wider(
    index='ref', 
    names_from='step',  
    values_from = ['var_1', 'var_2', 'var_3'],
    names_glue = "step {step} - {_value}")
.sort_index(axis=1)
) 
    ref  step 1 - var_1  step 1 - var_2  step 1 - var_3  ...  step 3 - var_3  step 4 - var_1  step 4 - var_2  step 4 - var_3
0  ref1               5              11              11  ...              10               9               6               6
1  ref2              12               6               6  ...              12              90               9               9

[2 rows x 13 columns]

Names_glue допускает комбинацию параметров values_from и names_from — в приведенном выше коде {step} — это аргумент name_from, а {_value} — заполнитель для values_from

Если мы строго придерживаемся вашего вывода, то фильтр должен выполняться в столбце step только для значений меньше 3:

(df
.loc[df.step < 3]
.pivot_wider(
    index='ref', 
    names_from='step', 
    names_glue = "step {step} - {_value}")
.sort_index(axis=1)
) 
    ref  step 1 - var_1  step 1 - var_2  step 1 - var_3  step 2 - var_1  step 2 - var_2  step 2 - var_3
0  ref1               5              11              11               7               8               8
1  ref2              12               6               6               9               9               9

Привет, это именно то, чего я хочу добиться, спасибо :) Я получил эту ошибку, когда запускаю ее для своих данных: «Индекс содержит повторяющиеся записи, не может изменить форму». Я пытался удалить другие столбцы, чтобы избежать помех, но это не сработает, есть идеи?

chris_olv 11.01.2023 10:10

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

sammywemmy 11.01.2023 10:28

Я обновил свой вопрос, я создал столбец «ссылка», который будет уникальным после завершения преобразования.

chris_olv 11.01.2023 11:08

Пожалуйста, поделитесь текстом, а не фотографиями. Вместо этого поделитесь файлом excel, если U csn

sammywemmy 11.01.2023 11:20

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