1. 程式人生 > >pandas中Series的多級索引

pandas中Series的多級索引

假設我們想分析2017年和2018年廣東,廣西,湖南的人口數。如果使用Series進行儲存的話,比較直接的方法如下:

In[1]index = [('廣東',2017),('廣東',2018),('廣西', 2017),('廣西', 2018),('湖
南',2017),('湖南', 2018)]

In[2]populations = [3387964,658964,
                458752,698256,
                125874,658963]

In[3]pop = pd.Series(populations, index=index)
In[4]pop
out[0]
(廣東, 2017)    3387964
(廣東, 2018)     658964
(廣西, 2017)     458752
(廣西, 2018)     698256
(湖南, 2017)     125874
(湖南, 2018)     658963
dtype: int64

通過切片獲取資料:

In [9]: pop[('廣東',2017):('廣西', 2017)]
Out[9]:
(廣東, 2017)    3387964
(廣東, 2018)     658964
(廣西, 2017)     458752
dtype: int64

但是這種做法不方便,假設我想獲取2017年這三個省份的人口數,不得不採用複雜的辦法:

In [12]: pop[[i for i in pop.index if i[1]==2017]]
Out[12]:
(廣東, 2017)    3387964
(廣西, 2017)     458752
(湖南, 2017)     125874
dtype: int64

這麼做雖然也能達到所要的結果,但是與pandas讓人崇拜又喜歡的切片相比,這種做法不夠簡潔、直觀。而多級索引可以解決這個問題:

我們使用pandas中MultiIndex建立多級索引:

In [13]: index = pd.MultiIndex.from_tuples(index)

In [14]: index
Out[14]:
MultiIndex(levels=[['廣東', '廣西', '湖南'], [2017, 2018]],
           labels=[[0, 0, 1, 1, 2, 2], [0, 1, 0, 1, 0, 1]])

MultiIndex裡有一個標籤表示索引的等級,

於是我們將前面建立的pop的索引重置:

In [15]: pop = pop.reindex(index)

In [16]: pop
Out[16]:
廣東  2017    3387964
    2018     658964
廣西  2017     458752
    2018     698256
湖南  2017     125874
    2018     658963
dtype: int64

如上圖所示,其中前兩列表示多級索引,第三列是資料。此時,我們可以通過切片很方便的獲取2017的人口數:

In [17]: pop[:,2017]
Out[17]:
廣東    3387964
廣西     458752
湖南     125874
dtype: int64

注意到沒有,其實上面的pop完全可以用一個表格來表示,也就是轉換成一個DataFrame:

In [18]: pop_df = pop.unstack()
Out[18]:pop_df
       2017    2018
廣東  3387964  658964
廣西   458752  698256
湖南   125874  658963

與unstack()相反的操作是stack():

In [22]: pop_df.stack()
Out[22]:
廣東  2017    3387964
    2018     658964
廣西  2017     458752
    2018     698256
湖南  2017     125874
    2018     658963
dtype: int64