枢纽分析后,

时间:2019-04-10 20:16:47

标签: python pandas dataframe pivot reshape

我正在构建用于公共交通数据的分析工具,并希望对熊猫数据框中的数据进行重新排序,可以使用以下示例对其进行最好的解释:

我最初的数据形状是:

            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

我将不调整数据框的形状,以使日期为顶级索引,而当前的较低级别信息PopulationGDP 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 个答案:

答案 0 :(得分:2)

交换级别和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

答案 1 :(得分:1)

从广义上讲,您想要执行以下操作:

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的列具有相反的顺序,以在人均GDP之前获得“人口”。在某些情况下,如果有人想要显式排序而不是同时出现字母顺序(或相反),这可能就行不通了。