給妹子講python-S02E16多級索引Pandas的取值、分片與運算
python,不管你懂沒懂,反正妹子是搞懂了
轉載請註明:知乎專欄《給妹子講python》
【要點搶先看】
1.Pandas數據類型多級索引的取值方法2.Pandas數據類型多級索引的分片方法3.多級Series與DataFrame的轉換4.多級DataFrame的行列統計
【妹子說】接著上一集吧,說說多級索引下Pandas數據類型的取值方法。
沒問題,其實只用緊緊抓住一條:多級索引本質還是索引!就是和之前介紹的Series、DataFrame相比,在原來的基礎上增加了索引的數據維度。
更直觀的,我們舉Series的例子來看,繼續使用上一集中用到的pop數據對象:
California 2008 33870000 2018 37250000New York 2008 18970000 2018 19370000Texas 2008 20850000 2018 25140000dtype: int64
首先,可以通過指定每個索引值來獲取單個元素值,我們看看2008年New York的人口數量:
print(pop[New York,2008])18970000
好,那如果我們只想指定二維索引中的其中一個索引,比如,我們只想看看New York所有年份的人口數呢?
print(pop[New York])2008 189700002018 19370000dtype: int64
同理,我們想看看2008所有州的人口數據呢?
print(pop[:,2008])California 33870000New York 18970000Texas 20850000dtype: int64
【妹子說】看上去不難,那我們再試試切片的使用?也分別針對兩個不同的索引。
沒問題,先對州索引進行切片,我們看看從加州到紐約的人口數據:
print(pop.loc[California:New York])California 2008 33870000 2018 37250000New York 2008 18970000 2018 19370000dtype: int64
然後再對另一個索引進行切片,看看2008到2018年所有州的人口數據
print(pop.loc[:, 2008:2018])California 2008 33870000 2018 37250000New York 2008 18970000 2018 19370000Texas 2008 20850000 2018 25140000dtype: int64
【妹子說】那我們之前學過的過濾取值和花哨索引也是一樣的啦
對,其實多級索引就是多了一維索引數據而已,本質上並無二異,我們利用過濾語法看看大於30000000的州和年份:
print(pop[pop > 30000000])California 2008 33870000 2018 37250000dtype: int64
像我們之前使用的花哨索引,跳過紐約州,單獨取加州和德州的數據,手法上都是一樣的:
print(pop[[California, Texas]])California 2008 33870000 2018 37250000Texas 2008 20850000 2018 25140000dtype: int64
接下來我們再看看DataFrame的多級索引如何使用,我們使用上一集中的那個四維DataFrame對象df_data來舉例:
name Tom Bill age 22 18 22 18year visit 2008 1 0.676136 -1.782380 -1.535020 -1.449538 2 -0.064762 0.357951 0.825011 -1.5696312018 1 1.458805 0.012029 -0.569635 0.558863 2 -0.350953 -0.848883 0.954154 -0.744795
因為DataFrame數據類型的基本索引是列索引,索引首先是應用到列上:
首先訪問Tom的數據,數據也因此從四維降維到了三維:
print(df_data[Tom])age 22 18year visit 2008 1 0.676136 -1.782380 2 -0.064762 0.3579512018 1 1.458805 0.012029 2 -0.350953 -0.848883
再進一步,訪問Tom年齡為22歲時的數據,將三維DataFrame降維變成了二維Series對象:
print(df_data[Tom,22])year visit2008 1 0.676136 2 -0.0647622018 1 1.458805 2 -0.350953Name: (Tom, 22), dtype: float64
後續選擇2008年的數據,將二維Series降為一維:
print(df_data[Tom,22][2008])visit1 0.6761362 -0.064762Name: (Tom, 22), dtype: float64
最後我們選取visit=1時的值,即最終定位到具體的一個值:
print(df_data[Tom,22][2008,1])0.676136437453
當然,之前介紹過的loc、iloc、ix索引器都可以在DataFrame的多級索引中使用:
首先我們使用iloc索引器,iloc索引器中均使用索引序號進行分片:
name Tom Bill age 22 18 22 18year visit 2008 1 1.064548 1.401008 -0.297243 0.577054 2 -0.558498 0.207713 -0.587791 1.9645622018 1 0.943348 0.916951 -0.366266 0.609855 2 0.744437 -1.901744 -0.049319 0.905967print(df_data.iloc[:2, :3])name Tom Billage 22 18 22year visit 2008 1 1.064548 1.401008 -0.297243 2 -0.558498 0.207713 -0.587791
仔細看不難發現,列索引是和age索引一致,而不是和name索引對齊
同理,就如同我們在前面的一集中所述,DataFrame一般用序號進行行的索引,用名稱進行列的索引,因此,採用多級索引的DataFrame數據類型使用ix索引器會更方便一些:
print(df_data.ix[:3,Tom])age 22 18year visit 2008 1 -0.015534 -1.482595 2 0.940742 0.1345952018 1 1.631052 2.229797
通過這種方法,我們就取得了頭三行里Tom的數據了。
不過這裡我們要強調一點,對MultiIndex進行切片是有一個前提的,那就是索引必須是按字典順序進行排列的,Pandas數據類型通過調用sort_index( )方法即可實現索引的排序。
我們再來說說多級索引的轉換問題:
當然,還是舉多級索引Series pop的例子,我們可以在不同方向上將多級索引轉換為DataFrame數據類型
print(pop.unstack(level=0))print(pop.unstack(level=1))state California New York Texasyear 2008 33870000 18970000 208500002018 37250000 19370000 25140000year 2008 2018state California 33870000 37250000New York 18970000 19370000Texas 20850000 25140000
甚至我們可以不用任何一列作為索引,而是採用默認的整數序列作為索引:
print(pop.reset_index(name=population)) state year population0 California 2008 338700001 California 2018 372500002 New York 2008 189700003 New York 2018 193700004 Texas 2008 208500005 Texas 2018 25140000
這樣,state、year以及我們新增的列名population就構成了一個新的DataFrame數據類型,當然,反過來,我們可以重新選擇任意兩列,如:state、population作為兩個索引列:
print(pop_un.set_index([state ,population]))state population California 33870000 2008 37250000 2018New York 18970000 2008 19370000 2018Texas 20850000 2008 25140000 2018
最後,我們來介紹一下多級索引DataFrame的求和、求平均值操作長什麼樣?簡單的說,多級索引可以針對數據子集進行操作。
我們仍然以這個多級DataFrame數據類型為例:
name Tom Bill age 22 18 22 18year visit 2008 1 -0.970482 0.064716 0.751445 -1.097711 2 1.356850 1.237055 1.584640 -0.2946232018 1 0.020507 1.071861 -0.839664 -1.135540 2 -1.578075 -0.774585 -0.786074 0.834400
我們先求每年的均值,這是橫向上的統計:
print(df_data.mean(level=year))name Tom Bill age 22 18 22 18year 2008 0.193184 0.650886 1.168042 -0.6961672018 -0.778784 0.148638 -0.812869 -0.150570
再從另一個方向上,按年齡來,求每個年齡對應的值的和。
print(df_data.sum(axis=1, level=age))age 18 22year visit 2008 1 -1.032995 -0.219037 2 0.942433 2.9414902018 1 -0.063678 -0.819157 2 0.059815 -2.364149
【妹子說】多級索引概念上好理解,但是操作細節上其實內容挺多的,兩集內容下來,收穫還是挺大的。
推薦閱讀:
※Pandas學習-6concat合併
※【翻譯】《利用Python進行數據分析·第2版》第5章(中)pandas入門
※pandas dataFrame 繪圖函數—plot學習筆記
※Pandas學習-8pandas plot圖表
※如何與pandas愉快地玩耍(一)