Это мой исходный фрейм данных:
Я хочу преобразовать фрейм данных в:
Я попытался использовать следующие строки кода: df.melt преобразует данные в структуру ниже, но Pivot_table не работает и показывает пустой фрейм данных:
# Melt the DataFrame
df_melt = df.melt(id_vars=['A', 'B', 'C', 'D', 'E'], var_name='Type', value_name='Value')
# Split the 'Type' column into 'Delivery Year' and 'Type'
df_melt[['Delivery Year', 'Type']] = df_melt['Type'].str.rsplit('_', n=1, expand=True)
# Pivot the DataFrame
pivot_df = df_melt.pivot_table(index=['A', 'B', 'C', 'D', 'E', 'Delivery Year'], columns='Type', values='Value', fill_value=0).reset_index()
Чтобы воссоздать мой фрейм данных, используйте следующий код:
df = pd.DataFrame({
'A': 'abc',
'B': 'abc',
'C': np.NaN,
'D': np.NaN,
'E': 'abc',
'Year 2020_AA': [0],
'Year 2020_AB': [0],
'Year 2021_AA': [0],
'Year 2021_AB': [0]
})
Любое руководство приветствуется.
Код
out = (df.set_index(['A', 'B', 'C', 'D', 'E'])
.pipe(lambda x: x.set_axis(
x.columns.str.split(' ').str[1].str.split('_', expand=True), axis=1)
)
.stack(0).reset_index().rename({'level_5': 'Year'}, axis=1)
)
вне:
Чтобы сделать приведенный выше код более понятным, он будет выглядеть так:
tmp = df.set_index(['A', 'B', 'C', 'D', 'E'])
idx = tmp.columns.str.split(' ').str[1].str.split('_', expand=True)
idx.names = ['Year',None]
out = tmp.set_axis(idx, axis=1).stack(0,future_stack=True).reset_index()
тот же результат
Один из вариантов — janitor.pivot_longer , где вы передаете регулярное выражение для изменения формы кадра данных. «.value» указывает, что эта часть столбца должна оставаться заголовком:
# pip install pyjanitor
import pandas as pd
import janitor
(df
.pivot_longer(
index=['A','B','C','D','E'],
names_to = ('Year','.value'),
names_pattern=r"Year\s(\d+)_(.+)")
)
A B C D E Year AA AB
0 abc abc NaN NaN abc 2020 0 0
1 abc abc NaN NaN abc 2021 0 0
Это хорошо работает! Большое спасибо :)