pandas中Series的多級索引
阿新 • • 發佈:2018-11-03
假設我們想分析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裡有一個標籤表示索引的等級,
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