Python科学计算之Pandas基础学习
Python科學(xué)計(jì)算之Pandas基礎(chǔ)學(xué)習(xí)
導(dǎo)入Pandas
我們首先要導(dǎo)入我們的演出明星——Pandas。
這是導(dǎo)入Pandas的標(biāo)準(zhǔn)方式。顯然,我們不希望每時(shí)每刻都在程序中寫’pandas’,但是保持代碼簡潔、避免命名沖突還是相當(dāng)重要的。因而我們折衷一下,用‘pd’代替“pandas’。如果你仔細(xì)查看其他人使用Pandas的代碼,你會(huì)發(fā)現(xiàn)這條導(dǎo)入語句。
Pandas的數(shù)據(jù)類型
Pandas基于兩種數(shù)據(jù)類型:series與dataframe。
一個(gè)series是一個(gè)一維的數(shù)據(jù)類型,其中每一個(gè)元素都有一個(gè)標(biāo)簽。如果你閱讀過這個(gè)系列的關(guān)于Numpy的文章,你就可以發(fā)現(xiàn)series類似于Numpy中元素帶標(biāo)簽的數(shù)組。其中,標(biāo)簽可以是數(shù)字或者字符串。
一個(gè)dataframe是一個(gè)二維的表結(jié)構(gòu)。Pandas的dataframe可以存儲(chǔ)許多種不同的數(shù)據(jù)類型,并且每一個(gè)坐標(biāo)軸都有自己的標(biāo)簽。你可以把它想象成一個(gè)series的字典項(xiàng)。
將數(shù)據(jù)導(dǎo)入Pandas
在我們開始挖掘與分析之前,我們首先需要導(dǎo)入能夠處理的數(shù)據(jù)。幸好,Pandas在這一點(diǎn)要比Numpy更方便。
在這里我推薦你使用自己所感興趣的數(shù)據(jù)集來使用。你的或其他國家的政府網(wǎng)站上會(huì)有一些好的數(shù)據(jù)源。例如,你可以搜索英國政府?dāng)?shù)據(jù)或美國政府?dāng)?shù)據(jù)來獲取數(shù)據(jù)源。當(dāng)然,Kaggle是另一個(gè)好用的數(shù)據(jù)源。
在此,我將采用英國政府?dāng)?shù)據(jù)中關(guān)于降雨量數(shù)據(jù),因?yàn)樗麄兪忠子谙螺d。此外,我還下載了一些日本降雨量的數(shù)據(jù)來使用。
這里我們從csv文件中讀取到了數(shù)據(jù),并將他們存入了dataframe中。我們只需要調(diào)用read_csv函數(shù)并將csv文件的路徑作為函數(shù)參數(shù)即可。header關(guān)鍵字告訴Pandas這些數(shù)據(jù)是否有列名,在哪里。如果沒有列名,你可以將其置為None。Pandas非常智能,所以你可以省略這一關(guān)鍵字。
將你的數(shù)據(jù)準(zhǔn)備好以進(jìn)行挖掘和分析
現(xiàn)在我們已經(jīng)將數(shù)據(jù)導(dǎo)入了Pandas。在我們開始深入探究這些數(shù)據(jù)之前,我們一定迫切地想大致瀏覽一下它們,并從中獲得一些有用信息,幫助我們確立探究的方向。
想要快速查看前x行數(shù)據(jù):
我們僅僅需要使用head()函數(shù)并傳入我們期望獲得的行數(shù)。
你將獲得一個(gè)類似下圖一樣的表:
另一方面,你可能想要獲得最后x行的數(shù)據(jù):
類似于head,我們只需要調(diào)用tail函數(shù)并傳入我們想獲取的行數(shù)。需要注意的是,Pandas不是從dataframe的結(jié)尾處開始倒著輸出數(shù)據(jù),而是按照它們在dataframe中固有的順序輸出給你。
你將獲得類似下圖的表
當(dāng)你在Pandas中查找列時(shí),你通常需要使用列名。這樣雖然非常便于使用,但有時(shí)候,數(shù)據(jù)可能會(huì)有特別長的列名,例如,有些列名可能是問卷表中的某整個(gè)問題。把這些列名變短會(huì)讓你的工作更加輕松:
有一點(diǎn)需要注意的是,在這里我故意讓所有列的標(biāo)簽都沒有空格和橫線。后面你將會(huì)看到,如果我們這樣命名變量,Pandas會(huì)將它們存成什么類型。
?你將獲得同之前一樣的數(shù)據(jù),但是列名已經(jīng)變了:
另一件你很想知道的關(guān)于你的數(shù)據(jù)的重要的事情是數(shù)據(jù)一共有多少條目。在Pandas中,一個(gè)條目等同于一行,所以我們可以通過len方法獲取數(shù)據(jù)的行數(shù),即條目數(shù)。
這將給你一個(gè)整數(shù)告訴你數(shù)據(jù)的行數(shù)。在我的數(shù)據(jù)集中,我有33行。
此外,你可能需要知道你數(shù)據(jù)的一些基本的統(tǒng)計(jì)信息。Pandas讓這件事變得非常簡單。
這將返回一個(gè)包含多種統(tǒng)計(jì)信息的表格,例如,計(jì)數(shù),均值,標(biāo)準(zhǔn)方差等。它看起來像這樣:
?
過濾
當(dāng)你查看你的數(shù)據(jù)集時(shí),你可能希望獲得一個(gè)特殊的樣本數(shù)據(jù)。例如,如果你有一個(gè)關(guān)于工作滿意度的問卷調(diào)查數(shù)據(jù),你可能想要獲得所有在同一行業(yè)或同一年齡段的人的數(shù)據(jù)。
Pandas為我們提供了多種方法來過濾我們的數(shù)據(jù)并提取出我們想要的信息。有時(shí)候你想要提取一整列。可以直接使用列標(biāo)簽,非常容易。
注意到當(dāng)我們提取了一列,Pandas將返回一個(gè)series,而不是一個(gè)dataframe。是否還記得,你可以將dataframe視作series的字典。所以,如果我們?nèi)〕隽四骋涣?#xff0c;我們獲得的自然是一個(gè)series。
還記得我所說的命名列標(biāo)簽的注意事項(xiàng)嗎?不使用空格和橫線等可以讓我們以訪問類屬性相同的方法來訪問列,即使用點(diǎn)運(yùn)算符。
這里返回的結(jié)果和之前的一模一樣,即一個(gè)包含我們所選列的數(shù)據(jù)的series。
如果你讀過這一系列中Numpy那一篇帖子,你可能會(huì)記得一項(xiàng)技術(shù)叫做‘boolean masking’,即我們可以在數(shù)組上運(yùn)行一個(gè)條件語句來獲得對(duì)應(yīng)的布爾值數(shù)組。好,我們也可以在Pandas中做同樣的事。
上述代碼將范圍一個(gè)布爾值的dataframe,其中,如果9、10月的降雨量低于1000毫米,則對(duì)應(yīng)的布爾值為‘True’,反之,則為’False’。
我們也可以使用這些條件表達(dá)式來過濾一個(gè)已知的dataframe。
這將返回一個(gè)僅僅包含9、10月降雨量低于1000mm的條目的dataframe。
你也可以使用多條條件表達(dá)式來進(jìn)行過濾:
這將返回rain_octsep小于1000并且outflow_octsep小于4000的那些條目。
值得注意的是,由于操作符優(yōu)先級(jí)的問題,在這里你不可以使用關(guān)鍵字‘a(chǎn)nd’,而只能使用’&’與括號(hào)
好消息是,如果在你的數(shù)據(jù)中有字符串,你也可以使用字符串方法來過濾數(shù)據(jù)。
注意到你必須使用.str.[string method],你不能直接在字符串上直接調(diào)用字符串方法。這一語句返回1990年代的所有條目。
索引
前幾部分為我們展示了如何通過列操作來獲得數(shù)據(jù)。實(shí)際上,Pandas同樣有標(biāo)簽化的行操作。這些行標(biāo)簽可以是數(shù)字或是其他標(biāo)簽。獲取行數(shù)據(jù)的方法也取決于這些標(biāo)簽的類型。
?如果你的行有數(shù)字索引,你可以使用iloc引用他們:
iloc僅僅作用于數(shù)字索引。它將會(huì)返回該行的一個(gè)series。在返回的series中,這一行的每一列都是一個(gè)獨(dú)立的元素。
?可能在你的數(shù)據(jù)集里有年份的列,或者年代的列,并且你希望可以用這些年份或年代來索引某些行。這樣,我們可以設(shè)置一個(gè)(或多個(gè))新的索引。
這將會(huì)給’water_year’一個(gè)新的索引值。注意到列名雖然只有一個(gè)元素,卻實(shí)際上需要包含于一個(gè)列表中。如果你想要多個(gè)索引,你可以簡單地在列表中增加另一個(gè)列名。
在上面這個(gè)例子中,我們把我們的索引值全部設(shè)置為了字符串。這意味著我們不可以使用iloc索引這些列了。這種情況該如何?我們使用loc。
這里,loc和iloc一樣會(huì)返回你所索引的行數(shù)據(jù)的一個(gè)series。唯一的不同是此時(shí)你使用的是字符串標(biāo)簽進(jìn)行引用,而不是數(shù)字標(biāo)簽。
ix是另一個(gè)常用的引用一行的方法。那么,如果loc是字符串標(biāo)簽的索引方法,iloc是數(shù)字標(biāo)簽的索引方法,那什么是ix呢?事實(shí)上,ix是一個(gè)字符串標(biāo)簽的索引方法,但是它同樣支持?jǐn)?shù)字標(biāo)簽索引作為它的備選。
正如loc和iloc,上述代碼將返回一個(gè)series包含你所索引的行的數(shù)據(jù)。
既然ix可以完成loc和iloc二者的工作,為什么還需要它們呢?最主要的原因是ix有一些輕微的不可預(yù)測性。還記得我說數(shù)字標(biāo)簽索引是ix的備選嗎?數(shù)字標(biāo)簽可能會(huì)讓ix做出一些奇怪的事情,例如將一個(gè)數(shù)字解釋成一個(gè)位置。而loc和iloc則為你帶來了安全的、可預(yù)測的、內(nèi)心的寧靜。然而必須指出的是,ix要比loc和iloc更快。
通常我們都希望索引是整齊有序地。我們可以在Pandas中通過調(diào)用sort_index來對(duì)dataframe實(shí)現(xiàn)排序。
由于我的所以已經(jīng)是有序的了,所以為了演示,我設(shè)置了關(guān)鍵字參數(shù)’ascending’為False。這樣,我的數(shù)據(jù)會(huì)以降序排列。
當(dāng)你為一列數(shù)據(jù)設(shè)置了一個(gè)索引時(shí),它們將不再是數(shù)據(jù)本身了。如果你想把索引設(shè)置為原始數(shù)據(jù)的形式,你可以使用和set_index相反的操作——reset_index。
這將返回?cái)?shù)據(jù)原始的索引形式。
對(duì)數(shù)據(jù)集應(yīng)用函數(shù)
有時(shí)候你會(huì)想以某些方式改變或是操作你數(shù)據(jù)集中的數(shù)據(jù)。例如,如果你有一列年份的數(shù)據(jù)而你希望創(chuàng)建一個(gè)新的列顯示這些年份所對(duì)應(yīng)的年代。Pandas對(duì)此給出了兩個(gè)非常有用的函數(shù),apply和applymap。
這會(huì)創(chuàng)建一個(gè)名為‘year‘的新列。這一列是由’water_year’列所導(dǎo)出的。它獲取的是主年份。這便是使用apply的方法,即如何對(duì)一列應(yīng)用一個(gè)函數(shù)。如果你想對(duì)整個(gè)數(shù)據(jù)集應(yīng)用某個(gè)函數(shù),你可以使用dataset.applymap()。
操作一個(gè)數(shù)據(jù)集結(jié)構(gòu)
另一件經(jīng)常會(huì)對(duì)dataframe所做的操作是為了讓它們呈現(xiàn)出一種更便于使用的形式而對(duì)它們進(jìn)行的重構(gòu)。
首先,groupby:
grouby所做的是將你所選擇的列組成一組。上述代碼首先將年代組成一組。雖然這樣做沒有給我們帶來任何便利,但我們可以緊接著在這個(gè)基礎(chǔ)上調(diào)用其它方法,例如max, min, mean等。例子中,我們可以得到90年代的均值。
你也可以對(duì)多行進(jìn)行分組操作:
接下來的unstack操作可能起初有一些困惑。它的功能是將某一列前置成為列標(biāo)簽。我們最好如下看看它的實(shí)際效果。
這個(gè)操作會(huì)將我們在上面小節(jié)創(chuàng)建的dataframe轉(zhuǎn)變成如下形式。它將標(biāo)識(shí)‘year’索引的第0列推起來,變?yōu)榱肆袠?biāo)簽。
我們再附加一個(gè)unstack操作。這次我們對(duì)’rain_octsep’索引的第1列操作:
現(xiàn)在,在我們下一個(gè)操作前,我們首先創(chuàng)造一個(gè)新的dataframe。
上述代碼為我們創(chuàng)建了如下的dataframe,我們將對(duì)它進(jìn)行pivot操作。
pivot實(shí)際上是在本文中我們已經(jīng)見過的操作的組合。首先,它設(shè)置了一個(gè)新的索引(set_index()),然后它對(duì)這個(gè)索引排序(sort_index()),最后它會(huì)進(jìn)行unstack操作。組合起來就是一個(gè)pivot操作。看看你能不能想想會(huì)發(fā)生什么:
注意到最后有一個(gè).fillna(‘’)。這個(gè)pivot創(chuàng)造了許多空的或值為NaN的條目。我個(gè)人覺得我的dataframe被亂七八糟的NaN分散了注意力,所以使用了fillna(‘’)將他們變成了空字符串。你也可以輸入任何你喜歡的東西,例如一個(gè)0。我們也可以使用函數(shù)dropna(how=’any’)來刪除所有的帶有NaN的行。然而在這個(gè)例子里,它可能會(huì)把所有東西都刪了,所以我們沒有這樣做。
上述dataframe為我們展現(xiàn)了所有降雨量大于1250的年份中的總雨量。不可否認(rèn)的是,這個(gè)并不是一個(gè)pivot的最好的示范,但是希望你能get到它的核心。看看你能在你自己的數(shù)據(jù)集中想出什么點(diǎn)子。
合并數(shù)據(jù)集
有時(shí)候你有兩個(gè)單獨(dú)的數(shù)據(jù)集,它們直接互相關(guān)聯(lián),而你想要比較它們的差異或者合并它們。沒問題,Pandas可以很容易實(shí)現(xiàn):
開始時(shí)你需要通過’on’關(guān)鍵字參數(shù)指定你想要合并的列。你也可以忽略這個(gè)參數(shù),這樣Pandas會(huì)自動(dòng)確定合并哪列。
如下你可以看到,兩個(gè)數(shù)據(jù)集在年份這一類上已經(jīng)合并了。rain_jpn數(shù)據(jù)集僅僅包含年份以及降雨量。當(dāng)我們以年份這一列進(jìn)行合并時(shí),僅僅’jpn_rainfall’這一列和我們UK雨量數(shù)據(jù)集的對(duì)應(yīng)列進(jìn)行了合并。
采用Pandas快速繪制圖表
Matplotlib很好用,但是想要畫出一個(gè)中途下降的圖表還是需要費(fèi)一番功夫的。而有的時(shí)候你僅僅想要快速畫出一個(gè)數(shù)據(jù)的大致走勢來幫助你發(fā)掘搞清這些數(shù)據(jù)的意義。Pandas提供了plot函數(shù)滿足你的需求:
這里非常輕松快速地利用plot畫出了一個(gè)你的數(shù)據(jù)的圖表。利用這個(gè)圖表,你可以緊接著直觀地發(fā)現(xiàn)深入挖掘的方向。例如,如果你看我畫出的我數(shù)據(jù)的圖表,你可以看到1995年英國可能發(fā)生了干旱。
你也能發(fā)現(xiàn)英國的降雨量明顯低于日本,然而人們卻說英國雨下得很多!
存儲(chǔ)你的數(shù)據(jù)集
在清理、重構(gòu)以及挖掘完你的數(shù)據(jù)后,你通常會(huì)剩下一些非常重要有用的東西。你不僅應(yīng)當(dāng)保留下你的原始數(shù)據(jù),也同樣需要保存下你最新處理過的數(shù)據(jù)集。
上述代碼會(huì)將你的數(shù)據(jù)存入一個(gè)csv文件以備下次使用。
到此為止,我們簡單介紹了Pandas。
END
---------------------------
原文鏈接https://www.cnblogs.com/skying555/p/5914391.html
總結(jié)
以上是生活随笔為你收集整理的Python科学计算之Pandas基础学习的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Pandas常用I/O(一)------
- 下一篇: numpy中where函数的用法