Изменение порядка данных в пандах для мультииндекса после разворота - PullRequest
2 голосов
/ 10 апреля 2019

Я создаю инструмент анализа данных общественного транспорта и хочу переупорядочить данные в кадре данных 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

Как мне добиться этого с помощью панд? Я экспериментировал с 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'])

Ответы [ 2 ]

2 голосов
/ 10 апреля 2019

Поменять местами уровни и index_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
1 голос
/ 10 апреля 2019

На широком уровне вы хотите сделать что-то вроде этого:

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])

Сначала вы делаете разворот. Затем измените порядок уровней, чтобы поставить дату вверху. Это создает нечто не совсем правильное, тогда как MultiIndex предоставляет запись для каждого отдельного элемента.

Итак, во-вторых, сортируйте индекс столбцов по уровням, чтобы сгруппировать их. И вы в конечном итоге с этим:

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='\s\s+'), но это всего лишь небольшая ошибка.

Передав явные инструкции по сортировке для обоих уровней, вы также можете сделать level=1 для столбцов в обратном порядке, чтобы получить Население до ВВП на душу населения. Это может не сработать в других случаях, когда кому-то может потребоваться явное упорядочение, которое не совпадает с алфавитным (или наоборот).

...