#python #pandas #dataframe #pivot #reshape
#python #pandas #фрейм данных #pivot #изменение формы
Вопрос:
Я создаю инструмент анализа данных общественного транспорта и хочу изменить порядок данных в фрейме данных pandas, который лучше всего можно объяснить на следующем примере:
Моя первоначальная форма данных:
Population GDP per capita
date 2015 2016 2017 2015 2016 2017
country
France 66593366.0 66859768.0 67118648.0 40564.460707 41357.986933 42850.386280
Germany 81686611.0 82348669.0 82695000.0 47810.836011 48943.101805 50638.890964
Italy 60730582.0 60627498.0 60551416.0 36640.115578 38380.172412 39426.940797
Spain 46444832.0 46484062.0 46572028.0 34818.120507 36305.222132 37997.852337
Я не хочу изменять фрейм данных так, чтобы даты были индексом верхнего уровня и текущей информацией более низкого уровня Population
и GDP per capita
находились на более низком уровне. Результирующий фрейм данных должен выглядеть следующим образом:
2015 2016 2017
date Population GDP per capita Population GDP per capita Population GDP per capita
country
France 66593366.0 40564.460707 66859768.0 41357.986933 67118648.0 42850.386280
Germany 81686611.0 47810.836011 82348669.0 48943.101805 82695000.0 50638.890964
Italy 60730582.0 36640.115578 60627498.0 38380.172412 60551416.0 39426.940797
Spain 46444832.0 34818.120507 46484062.0 36305.222132 46572028.0 37997.852337
Как я могу добиться этого с помощью pandas? Я экспериментировал, swaplevel
но не смог получить ожидаемые результаты.
Фрейм данных получается из следующих данных с pivot
помощью операции:
country date Population GDP per capita GNI per capita
1 Germany 2017 82695000.0 50638.890964 51680.0
2 Germany 2016 82348669.0 48943.101805 49770.0
3 Germany 2015 81686611.0 47810.836011 48690.0
60 Spain 2017 46572028.0 37997.852337 37990.0
61 Spain 2016 46484062.0 36305.222132 36300.0
62 Spain 2015 46444832.0 34818.120507 34740.0
119 France 2017 67118648.0 42850.386280 43790.0
120 France 2016 66859768.0 41357.986933 42020.0
121 France 2015 66593366.0 40564.460707 41100.0
237 Italy 2017 60551416.0 39426.940797 39640.0
238 Italy 2016 60627498.0 38380.172412 38470.0
239 Italy 2015 60730582.0 36640.115578 36440.0
И следующее pivot
:
df_p = df_small.pivot(
index='country',
columns='date',
values=['Population', 'GDP per capita'])
Ответ №1:
Уровни подкачки и sort_index,
df_p.columns = df_p.columns.swaplevel(1,0)
df_p = df_p.sort_index(axis = 1)
date 2015 2016 2017
GDP per capita Population GDP per capita Population GDP per capita Population
country
France 40564.460707 66593366.0 41357.986933 66859768.0 42850.386280 67118648.0
Germany 47810.836011 81686611.0 48943.101805 82348669.0 50638.890964 82695000.0
Italy 36640.115578 60730582.0 38380.172412 60627498.0 39426.940797 60551416.0
Spain 34818.120507 46444832.0 36305.222132 46484062.0 37997.852337 46572028.0
Ответ №2:
На широком уровне вы хотите сделать что-то вроде этого:
df.pivot(index='country', columns='date', values=['GDP per capita' , 'Population'])
.reorder_levels(['date', None], axis=1) # the multiindex doesn't get a name, so None
.sort_index(level=[0, 1], axis=1, ascending=[True, False])
Сначала вы выполняете pivot. Затем измените порядок уровней, чтобы дата была вверху. Однако это создает что-то не совсем правильное, когда мультииндекс затем предоставляет запись для каждого отдельного элемента.
Итак, во-вторых, отсортируйте индекс столбцов по его уровням, чтобы сгруппировать их. И в итоге вы получаете это:
date 2015 2016 2017
Population GDP per capita Population GDP per capita Population GDP per capita
country
France 66593366.0 40564.460707 66859768.0 41357.986933 67118648.0 42850.386280
Germany 81686611.0 47810.836011 82348669.0 48943.101805 82695000.0 50638.890964
Italy 60730582.0 36640.115578 60627498.0 38380.172412 60551416.0 39426.940797
Spain 46444832.0 34818.120507 46484062.0 36305.222132 46572028.0 37997.852337
Кроме того, было бы здорово найти способ легкого чтения ваших данных вместо того, чтобы перебирать систему, используя, pd.read_csv(string_io_obj, sep='ss ')
но это всего лишь небольшая ошибка.
Передавая явные инструкции по сортировке для обоих уровней, вы также можете сделать level=1
так, чтобы столбцы имели обратный порядок, чтобы получить население до предельного ВВП. Это может не сработать в других случаях, когда кому-то может потребоваться явный порядок, который не является случайно алфавитным (или наоборот).