Я хочу использовать Python для чтения файла Excel и преобразования его в другую структуру (Пример).
Мой текущий подход следующий
Пример фрейма данных Python для создания области, отмеченной красным выше:
df = pd.DataFrame({'col1': {0: 'Year' , 1: 'Option' , 2: 'Category' , 3: 'Type' , 4: 'Country' , 5: 'Australia', 6: 'New Zealand'},
'col2': {0: '2024' , 1: 'S' , 2: 'FTE' , 3: 'A' , 4: '' , 5: '-1,0' , 6: '-2,0'},
'col3': {0: '' , 1: '' , 2: 'Budget' , 3: 'B' , 4: 'EUR' , 5: '-100,5' , 6: '-200,5'},
'col4': {0: '' , 1: '' , 2: '' , 3: 'C' , 4: 'EUR' , 5: '-1000' , 6: '-2000'},
'col5': {0: '' , 1: 'T' , 2: 'FTE' , 3: 'A' , 4: '' , 5: '1,0' , 6: '2,0'},
'col6': {0: '' , 1: '' , 2: 'Budget' , 3: 'B' , 4: 'EUR' , 5: '100,5' , 6: '200,5'},
'col7': {0: '' , 1: '' , 2: '' , 3: 'C' , 4: 'EUR' , 5: '1000' , 6: '2000'},
'col8': {0: '2025' , 1: 'S' , 2: 'FTE' , 3: 'A' , 4: '' , 5: '-3,0' , 6: '-4,0'},
'col9': {0: '' , 1: '' , 2: 'Budget' , 3: 'B' , 4: 'EUR' , 5: '-300,5' , 6: '-400,5'},
'col10': {0: '' , 1: '' , 2: '' , 3: 'C' , 4: 'EUR' , 5: '3000' , 6: '-4000'},
'col11': {0: '' , 1: 'T' , 2: 'FTE' , 3: 'A' , 4: '' , 5: '3,0' , 6: '4,0'},
'col12': {0: '' , 1: '' , 2: 'Budget' , 3: 'B' , 4: 'EUR' , 5: '300,5' , 6: '400,5'},
'col13': {0: '' , 1: '' , 2: '' , 3: 'C' , 4: 'EUR' , 5: '3000' , 6: '4000'},
})
Я изо всех сил пытаюсь прочитать данные и установить столбцы с несколькими индексами в фрейме данных, поскольку столбец страны не вписывается в иерархию.
Потому что мне приходится использовать df = pd.read_excel(...usecols='T:Z', header=None...
. Я читаю данные и заголовок отдельно, а затем добавляю заголовки с помощью df.columns = pd.MultiIndex.from_arrays(...)
.
Результат (на 2024 год) выглядит так
Здесь я застрял, я пытался использовать .stack
и .melt
для достижения целевой структуры, но не смог ее достичь.
Что касается красной области, вы можете использовать следующий код для получения желаемого формата:
table = df.T # Assuming "df" is the dataframe you gave
# Reset and eliminate the index
table.reset_index(inplace=True)
del table['index']
# Reset the dataframe to make the columns the first row
table.columns = table.iloc[0]
table = table[1:]
# Remove irrelevant columns
del table['Country']
del table['Category']
# Blank entries must be populated with the previous entry
def ReplaceBlankEntriesWithPrevious(col):
out = col.copy()
for i in range(1, len(col)+1):
out[i] = col[i] if col[i] != "" else out[i-1]
return out
table['Year'] = ReplaceBlankEntriesWithPrevious(table['Year'])
table['Option'] = ReplaceBlankEntriesWithPrevious(table['Option'])
# Set two of the three indexes
table.set_index(['Year', 'Option'], inplace=True)
# Swap the "Type" and "Country" positions
table = table.pivot(columns='Type')
table = table.stack(level=0)
table.rename_axis(index = {0:"Country"}, inplace=True)
# Optionally, you can swap the index order to put it in the order of
# Country, Year, Option
table = table.swaplevel(i=0, j=2)
table = table.swaplevel(i=1, j=2)
Обратите внимание, что я начал с транспонирования таблицы, поскольку и «Год», и «Опцион» были столбцами. Кроме того, мне пришлось заполнить пустые ячейки подразумеваемыми значениями. Это решение не самое элегантное, но оно выполняет свою работу. Я бы приветствовал более лаконичное решение.
Удивительный! это помогло решить проблему!