Как я могу развернуть фрейм данных с переменными столбцами даты?

У меня есть некоторый входной фрейм данных в качестве следующего примера:

import pandas as pd

df = pd.DataFrame(
    {
        "Name":["Ale", "Dan", "Hel"],
        "Project": ["A", "A", "B"],
        "10/04/2023 Formation": [24, 40, 40],
        "17/04/2023 Formation": [12, 24, 24],
        "10/04/2023 Holidays": [40, 40, 40],
        "17/04/2023 Holidays": [12, 40, 24],
     }
)

Как видно, некоторые столбцы представляют собой даты, относящиеся к определенному понятию (Формирование, Праздники, в данном случае).

Я хочу нормализовать эти столбцы, чтобы преобразовать их в строки (развернуть), но сохранить (группировать) каждый проект в своем собственном столбце; то есть я хотел бы выполнить преобразование фрейма данных, вывод которого будет примерно таким:

         Date Name Project  Formation  Holidays
0  10/04/2023  Ale       A         24        40
1  17/04/2023  Ale       A         12        12
2  10/04/2023  Dan       A         40        40
3  17/04/2023  Dan       A         24        40
4  10/04/2023  Hel       B         40        40
5  17/04/2023  Hel       B         24        40
Почему в 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
57
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

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

df = pd.DataFrame(
    {
        "Name":["Ale", "Dan", "Hel"],
        "Project": ["A", "A", "B"],
        "10/04/2023 Formation": [24, 40, 40],
        "17/04/2023 Formation": [12, 24, 24],
        "10/04/2023 Holidays": [40, 40, 40],
        "17/04/2023 Holidays": [12, 40, 24],
     }
)

# Unpivot the data using pd.melt()
df_melted = pd.melt(df, id_vars=["Name", "Project"], var_name = "Date_Concept", value_name = "Value")

# Separate the Date and Concept columns
df_melted[["Date", "Concept"]] = df_melted["Date_Concept"].str.split(" ", expand=True)
df_melted = df_melted.drop("Date_Concept", axis=1)

# Use pd.pivot_table() to reshape the dataframe
df_final = pd.pivot_table(df_melted, index=["Date", "Name", "Project"], columns = "Concept", values = "Value").reset_index()

# Reorder the columns
df_final = df_final[["Date", "Name", "Project", "Formation", "Holidays"]].sort_values(["Name", "Date", "Project"])

print(df_final)

Вы можете использовать pd.wide_to_long после переименования столбцов для переключения информации префикса и суффикса (04.10.2023 г. -> Формирование-04.10.2023 г.):

out = pd.wide_to_long(df.rename(columns=lambda x: '-'.join(x.split(maxsplit=1)[::-1])),
                      stubnames=['Formation', 'Holidays'], i=['Name', 'Project'],
                      j='Date', sep='-', suffix='.*').reset_index()

Выход:

>>> out
  Name Project        Date  Formation  Holidays
0  Ale       A  10/04/2023         24        40
1  Ale       A  17/04/2023         12        12
2  Dan       A  10/04/2023         40        40
3  Dan       A  17/04/2023         24        40
4  Hel       B  10/04/2023         40        40
5  Hel       B  17/04/2023         24        24

Используя уборщика pivot_longer:

# pip install janitor
import janitor

out = df.pivot_longer(['Name', 'Project'], sort_by_appearance=True,
                      names_to=('Date', '.value'),
                      names_pattern=r'(\d{2}/\d{2}/\d{4}) (.*)')

Или names_sep=' ' вместо names_pattern=r'(\d{2}/\d{2}/\d{4}) (.*)'.

Выход:

  Name Project        Date  Formation  Holidays
0  Ale       A  10/04/2023         24        40
1  Ale       A  17/04/2023         12        12
2  Dan       A  10/04/2023         40        40
3  Dan       A  17/04/2023         24        40
4  Hel       B  10/04/2023         40        40
5  Hel       B  17/04/2023         24        24

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