<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          整理了 25 個(gè) Pandas 實(shí)用技巧,拿走不謝!

          共 7860字,需瀏覽 16分鐘

           ·

          2020-08-27 14:35


          作者:『博客園』山陰少年?

          來源:www.cnblogs.com/jclian91/p/12305471.html

          原文:https://nbviewer.jupyter.org/github/justmarkham/pandas-videos/blob/master/top_25_pandas_tricks.ipynb


          首先我們需要先提前下載好示例數(shù)據(jù)集:

          • drinksbycountry.csv :?http://bit.ly/drinksbycountry
          • imdbratings.csv :?http://bit.ly/imdbratings
          • chiporders.csv :?http://bit.ly/chiporders
          • smallstockers.csv :?http://bit.ly/smallstocks
          • kaggletrain.csv :?http://bit.ly/kaggletrain
          • uforeports.csv :?http://bit.ly/uforeports

          利用以下代碼導(dǎo)入上述數(shù)據(jù)集:

          1. 顯示已安裝的版本

          輸入下面的命令查詢pandas版本:


          如果你還想知道pandas所依賴的模塊的版本,你可以使用show_versions()函數(shù):

          你可以查看到Python,pandas, Numpy, matplotlib等的版本信息。

          2. 創(chuàng)建示例DataFrame

          假設(shè)你需要?jiǎng)?chuàng)建一個(gè)示例DataFrame。有很多種實(shí)現(xiàn)的途徑,我最喜歡的方式是傳一個(gè)字典給DataFrame constructor,其中字典中的keys為列名,values為列的取值。

          現(xiàn)在如果你需要?jiǎng)?chuàng)建一個(gè)更大的DataFrame,上述方法則需要太多的輸入。在這種情況下,你可以使用Numpy的random.rand()函數(shù),告訴它行數(shù)和列數(shù),將它傳遞給DataFrame constructor:

          這種方式很好,但如果你還想把列名變?yōu)榉菙?shù)值型的,你可以強(qiáng)制地將一串字符賦值給columns參數(shù):

          你可以想到,你傳遞的字符串的長度必須與列數(shù)相同。

          3. 更改列名

          讓我們來看一下剛才我們創(chuàng)建的示例DataFrame:

          我更喜歡在選取pandas列的時(shí)候使用點(diǎn)(.),但是這對那么列名中含有空格的列不會生效。讓我們來修復(fù)這個(gè)問題。

          更改列名最靈活的方式是使用rename()函數(shù)。你可以傳遞一個(gè)字典,其中keys為原列名,values為新列名,還可以指定axis:

          使用這個(gè)函數(shù)最好的方式是你需要更改任意數(shù)量的列名,不管是一列或者全部的列。

          如果你需要一次性重新命令所有的列名,更簡單的方式就是重寫DataFrame的columns屬性:

          如果你需要做的僅僅是將空格換成下劃線,那么更好的辦法是使用str.replace()方法,這是因?yàn)槟愣疾恍枰斎胨械牧忻?br>
          上述三個(gè)函數(shù)的結(jié)果都一樣,可以更改列名使得列名中不含有空格:

          最后,如果你需要在列名中添加前綴或者后綴,你可以使用add_prefix()函數(shù):

          或者使用add_suffix()函數(shù):

          4. 行序反轉(zhuǎn)

          讓我們來看一下drinks這個(gè)DataFame:

          該數(shù)據(jù)集描述了每個(gè)國家的平均酒消費(fèi)量。如果你想要將行序反轉(zhuǎn)呢?

          最直接的辦法是使用loc函數(shù)并傳遞::-1,跟Python中列表反轉(zhuǎn)時(shí)使用的切片符號一致:

          如果你還想重置索引使得它從0開始呢?

          你可以使用reset_index()函數(shù),告訴他去掉完全拋棄之前的索引:

          你可以看到,行序已經(jīng)反轉(zhuǎn),索引也被重置為默認(rèn)的整數(shù)序號。

          5. 列序反轉(zhuǎn)

          跟之前的技巧一樣,你也可以使用loc函數(shù)將列從左至右反轉(zhuǎn):

          逗號之前的冒號表示選擇所有行,逗號之后的::-1表示反轉(zhuǎn)所有的列,這就是為什么country這一列現(xiàn)在在最右邊。

          6. 通過數(shù)據(jù)類型選擇列

          這里有drinks這個(gè)DataFrame的數(shù)據(jù)類型:

          假設(shè)你僅僅需要選取數(shù)值型的列,那么你可以使用select_dtypes()函數(shù):

          這包含了int和float型的列。

          你也可以使用這個(gè)函數(shù)來選取數(shù)據(jù)類型為object的列:

          你還可以選取多種數(shù)據(jù)類型,只需要傳遞一個(gè)列表即可:

          你還可以用來排除特定的數(shù)據(jù)類型:

          7. 將字符型轉(zhuǎn)換為數(shù)值型

          讓我們來創(chuàng)建另一個(gè)示例DataFrame:

          這些數(shù)字實(shí)際上儲存為字符型,導(dǎo)致其數(shù)據(jù)類型為object:

          為了對這些列進(jìn)行數(shù)學(xué)運(yùn)算,我們需要將數(shù)據(jù)類型轉(zhuǎn)換成數(shù)值型。你可以對前兩列使用astype()函數(shù):

          但是,如果你對第三列也使用這個(gè)函數(shù),將會引起錯(cuò)誤,這是因?yàn)檫@一列包含了破折號(用來表示0)但是pandas并不知道如何處理它。

          你可以對第三列使用to_numeric()函數(shù),告訴其將任何無效數(shù)據(jù)轉(zhuǎn)換為NaN:

          如果你知道NaN值代表0,那么你可以fillna()函數(shù)將他們替換成0:

          最后,你可以通過apply()函數(shù)一次性對整個(gè)DataFrame使用這個(gè)函數(shù):

          僅需一行代碼就完成了我們的目標(biāo),因?yàn)楝F(xiàn)在所有的數(shù)據(jù)類型都轉(zhuǎn)換成float:

          8. 減小DataFrame空間大小

          pandas DataFrame被設(shè)計(jì)成可以適應(yīng)內(nèi)存,所以有些時(shí)候你可以減小DataFrame的空間大小,讓它在你的系統(tǒng)上更好地運(yùn)行起來。

          這是drinks這個(gè)DataFrame所占用的空間大?。?br>
          可以看到它使用了304.KB。

          如果你對你的DataFrame有操作方面的問題,或者你不能將它讀進(jìn)內(nèi)存,那么在讀取文件的過程中有兩個(gè)步驟可以使用來減小DataFrame的空間大小。

          第一個(gè)步驟是只讀取那些你實(shí)際上需要用到的列,可以調(diào)用usecols參數(shù):

          通過僅讀取用到的兩列,我們將DataFrame的空間大小縮小至13.6KB。

          第二步是將所有實(shí)際上為類別變量的object列轉(zhuǎn)換成類別變量,可以調(diào)用dtypes參數(shù):

          通過將continent列讀取為category數(shù)據(jù)類型,我們進(jìn)一步地把DataFrame的空間大小縮小至2.3KB。

          值得注意的是,如果跟行數(shù)相比,category數(shù)據(jù)類型的列數(shù)相對較小,那么catefory數(shù)據(jù)類型可以減小內(nèi)存占用。

          9. 按行從多個(gè)文件中構(gòu)建DataFrame

          假設(shè)你的數(shù)據(jù)集分化為多個(gè)文件,但是你需要將這些數(shù)據(jù)集讀到一個(gè)DataFrame中。

          舉例來說,我有一些關(guān)于股票的小數(shù)聚集,每個(gè)數(shù)據(jù)集為單天的CSV文件。這是第一天的:

          這是第二天的:

          這是第三天的:

          你可以將每個(gè)CSV文件讀取成DataFrame,將它們結(jié)合起來,然后再刪除原來的DataFrame,但是這樣會多占用內(nèi)存且需要許多代碼。

          更好的方式為使用內(nèi)置的glob模塊。你可以給glob()函數(shù)傳遞某種模式,包括未知字符,這樣它會返回符合該某事的文件列表。在這種方式下,glob會查找所有以stocks開頭的CSV文件:

          glob會返回任意排序的文件名,這就是我們?yōu)槭裁匆肞ython內(nèi)置的sorted()函數(shù)來對列表進(jìn)行排序。

          我們以生成器表達(dá)式用read_csv()函數(shù)來讀取每個(gè)文件,并將結(jié)果傳遞給concat()函數(shù),這會將單個(gè)的DataFrame按行來組合:

          不幸的是,索引值存在重復(fù)。為了避免這種情況,我們需要告訴concat()函數(shù)來忽略索引,使用默認(rèn)的整數(shù)索引:

          10. 按列從多個(gè)文件中構(gòu)建DataFrame

          上一個(gè)技巧對于數(shù)據(jù)集中每個(gè)文件包含行記錄很有用。但是如果數(shù)據(jù)集中的每個(gè)文件包含的列信息呢?

          這里有一個(gè)例子,dinks數(shù)據(jù)集被劃分成兩個(gè)CSV文件,每個(gè)文件包含三列:

          同上一個(gè)技巧一樣,我們以使用glob()函數(shù)開始。這一次,我們需要告訴concat()函數(shù)按列來組合:

          現(xiàn)在我們的DataFrame已經(jīng)有六列了。

          11. 從剪貼板中創(chuàng)建DataFrame

          假設(shè)你將一些數(shù)據(jù)儲存在Excel或者Google Sheet中,你又想要盡快地將他們讀取至DataFrame中。

          你需要選擇這些數(shù)據(jù)并復(fù)制至剪貼板。然后,你可以使用read_clipboard()函數(shù)將他們讀取至DataFrame中:

          和read_csv()類似,read_clipboard()會自動(dòng)檢測每一列的正確的數(shù)據(jù)類型:

          讓我們再復(fù)制另外一個(gè)數(shù)據(jù)至剪貼板:

          神奇的是,pandas已經(jīng)將第一列作為索引了:

          需要注意的是,如果你想要你的工作在未來可復(fù)制,那么read_clipboard()并不值得推薦。

          12. 將DataFrame劃分為兩個(gè)隨機(jī)的子集

          假設(shè)你想要將一個(gè)DataFrame劃分為兩部分,隨機(jī)地將75%的行給一個(gè)DataFrame,剩下的25%的行給另一個(gè)DataFrame。

          舉例來說,我們的movie ratings這個(gè)DataFrame有979行:

          我們可以使用sample()函數(shù)來隨機(jī)選取75%的行,并將它們賦值給"movies_1"DataFrame:

          接著我們使用drop()函數(shù)來舍棄“moive_1”中出現(xiàn)過的行,將剩下的行賦值給"movies_2"DataFrame:

          ??你可以發(fā)現(xiàn)總的行數(shù)是正確的:

          你還可以檢查每部電影的索引,或者"moives_1":

          或者"moives_2":

          需要注意的是,這個(gè)方法在索引值不唯一的情況下不起作用。

          讀者注:該方法在機(jī)器學(xué)習(xí)或者深度學(xué)習(xí)中很有用,因?yàn)樵谀P陀?xùn)練前,我們往往需要將全部數(shù)據(jù)集按某個(gè)比例劃分成訓(xùn)練集和測試集。該方法既簡單又高效,值得學(xué)習(xí)和嘗試。

          13. 通過多種類型對DataFrame進(jìn)行過濾

          讓我們先看一眼movies這個(gè)DataFrame:

          其中有一列是genre(類型):

          比如我們想要對該DataFrame進(jìn)行過濾,我們只想顯示genre為Action或者Drama或者Western的電影,我們可以使用多個(gè)條件,以"or"符號分隔:

          但是,你實(shí)際上可以使用isin()函數(shù)將代碼寫得更加清晰,將genres列表傳遞給該函數(shù):

          如果你想要進(jìn)行相反的過濾,也就是你將吧剛才的三種類型的電影排除掉,那么你可以在過濾條件前加上破浪號:

          這種方法能夠起作用是因?yàn)樵赑ython中,波浪號表示“not”操作。

          14. 從DataFrame中篩選出數(shù)量最多的類別

          假設(shè)你想要對movies這個(gè)DataFrame通過genre進(jìn)行過濾,但是只需要前3個(gè)數(shù)量最多的genre。

          我們對genre使用value_counts()函數(shù),并將它保存成counts(type為Series):

          該Series的nlargest()函數(shù)能夠輕松地計(jì)算出Series中前3個(gè)最大值:

          事實(shí)上我們在該Series中需要的是索引:

          最后,我們將該索引傳遞給isin()函數(shù),該函數(shù)會把它當(dāng)成genre列表:

          這樣,在DataFrame中只剩下Drame, Comdey, Action這三種類型的電影了。

          15. 處理缺失值

          讓我們來看一看UFO sightings這個(gè)DataFrame:

          你將會注意到有些值是缺失的。

          為了找出每一列中有多少值是缺失的,你可以使用isna()函數(shù),然后再使用sum():

          isna()會產(chǎn)生一個(gè)由True和False組成的DataFrame,sum()會將所有的True值轉(zhuǎn)換為1,F(xiàn)alse轉(zhuǎn)換為0并把它們加起來。

          類似地,你可以通過mean()和isna()函數(shù)找出每一列中缺失值的百分比。

          如果你想要舍棄那些包含了缺失值的列,你可以使用dropna()函數(shù):

          或者你想要舍棄那么缺失值占比超過10%的列,你可以給dropna()設(shè)置一個(gè)閾值:

          len(ufo)返回總行數(shù),我們將它乘以0.9,以告訴pandas保留那些至少90%的值不是缺失值的列。

          16. 將一個(gè)字符串劃分成多個(gè)列

          我們先創(chuàng)建另一個(gè)新的示例DataFrame:

          如果我們需要將“name”這一列劃分為三個(gè)獨(dú)立的列,用來表示first, middle, last name呢?我們將會使用str.split()函數(shù),告訴它以空格進(jìn)行分隔,并將結(jié)果擴(kuò)展成一個(gè)DataFrame:

          這三列實(shí)際上可以通過一行代碼保存至原來的DataFrame:

          如果我們想要?jiǎng)澐忠粋€(gè)字符串,但是僅保留其中一個(gè)結(jié)果列呢?比如說,讓我們以", "來劃分location這一列:

          如果我們只想保留第0列作為city name,我們僅需要選擇那一列并保存至DataFrame:

          17. 將一個(gè)由列表組成的Series擴(kuò)展成DataFrame

          讓我們創(chuàng)建一個(gè)新的示例DataFrame:

          這里有兩列,第二列包含了Python中的由整數(shù)元素組成的列表。

          如果我們想要將第二列擴(kuò)展成DataFrame,我們可以對那一列使用apply()函數(shù)并傳遞給Series constructor:

          通過使用concat()函數(shù),我們可以將原來的DataFrame和新的DataFrame組合起來:

          18. 對多個(gè)函數(shù)進(jìn)行聚合

          讓我們來看一眼從Chipotle restaurant chain得到的orders這個(gè)DataFrame:

          每個(gè)訂單(order)都有訂單號(order_id),包含一行或者多行。為了找出每個(gè)訂單的總價(jià)格,你可以將那個(gè)訂單號的價(jià)格(item_price)加起來。比如,這里是訂單號為1的總價(jià)格:

          如果你想要計(jì)算每個(gè)訂單的總價(jià)格,你可以對order_id使用groupby(),再對每個(gè)group的item_price進(jìn)行求和。

          但是,事實(shí)上你不可能在聚合時(shí)僅使用一個(gè)函數(shù),比如sum()。為了對多個(gè)函數(shù)進(jìn)行聚合,你可以使用agg()函數(shù),傳給它一個(gè)函數(shù)列表,比如sum()和count():

          這將告訴我們沒定訂單的總價(jià)格和數(shù)量。

          19. 將聚合結(jié)果與DataFrame進(jìn)行組合

          讓我們再看一眼orders這個(gè)DataFrame:

          如果我們想要增加新的一列,用于展示每個(gè)訂單的總價(jià)格呢?回憶一下,我們通過使用sum()函數(shù)得到了總價(jià)格:

          sum()是一個(gè)聚合函數(shù),這表明它返回輸入數(shù)據(jù)的精簡版本(reduced version )。

          換句話說,sum()函數(shù)的輸出:

          比這個(gè)函數(shù)的輸入要?。?br>
          解決的辦法是使用transform()函數(shù),它會執(zhí)行相同的操作但是返回與輸入數(shù)據(jù)相同的形狀:

          我們將這個(gè)結(jié)果存儲至DataFrame中新的一列:

          你可以看到,每個(gè)訂單的總價(jià)格在每一行中顯示出來了。

          這樣我們就能方便地甲酸每個(gè)訂單的價(jià)格占該訂單的總價(jià)格的百分比:

          20. 選取行和列的切片

          讓我們看一眼另一個(gè)數(shù)據(jù)集:

          這就是著名的Titanic數(shù)據(jù)集,它保存了Titanic上乘客的信息以及他們是否存活。

          如果你想要對這個(gè)數(shù)據(jù)集做一個(gè)數(shù)值方面的總結(jié),你可以使用describe()函數(shù):

          但是,這個(gè)DataFrame結(jié)果可能比你想要的信息顯示得更多。

          如果你想對這個(gè)結(jié)果進(jìn)行過濾,只想顯示“五數(shù)概括法”(five-number summary)的信息,你可以使用loc函數(shù)并傳遞"min"到"max"的切片:

          如果你不是對所有列都感興趣,你也可以傳遞列名的切片:

          21. 對MultiIndexed Series進(jìn)行重塑

          Titanic數(shù)據(jù)集的Survived列由1和0組成,因此你可以對這一列計(jì)算總的存活率:

          如果你想對某個(gè)類別,比如“Sex”,計(jì)算存活率,你可以使用groupby():

          如果你想一次性對兩個(gè)類別變量計(jì)算存活率,你可以對這些類別變量使用groupby():

          該結(jié)果展示了由Sex和Passenger Class聯(lián)合起來的存活率。它存儲為一個(gè)MultiIndexed Series,也就是說它對實(shí)際數(shù)據(jù)有多個(gè)索引層級。

          這使得該數(shù)據(jù)難以讀取和交互,因此更為方便的是通過unstack()函數(shù)將MultiIndexed Series重塑成一個(gè)DataFrame:

          該DataFrame包含了與MultiIndexed Series一樣的數(shù)據(jù),不同的是,現(xiàn)在你可以用熟悉的DataFrame的函數(shù)對它進(jìn)行操作。

          22. 創(chuàng)建數(shù)據(jù)透視表(pivot table)

          如果你經(jīng)常使用上述的方法創(chuàng)建DataFrames,你也許會發(fā)現(xiàn)用pivot_table()函數(shù)更為便捷:

          想要使用數(shù)據(jù)透視表,你需要指定索引(index), 列名(columns), 值(values)和聚合函數(shù)(aggregation function)。

          數(shù)據(jù)透視表的另一個(gè)好處是,你可以通過設(shè)置margins=True輕松地將行和列都加起來:

          這個(gè)結(jié)果既顯示了總的存活率,也顯示了Sex和Passenger Class的存活率。

          最后,你可以創(chuàng)建交叉表(cross-tabulation),只需要將聚合函數(shù)由"mean"改為"count":

          這個(gè)結(jié)果展示了每一對類別變量組合后的記錄總數(shù)。

          23. 將連續(xù)數(shù)據(jù)轉(zhuǎn)變成類別數(shù)據(jù)

          讓我們來看一下Titanic數(shù)據(jù)集中的Age那一列:

          它現(xiàn)在是連續(xù)性數(shù)據(jù),但是如果我們想要將它轉(zhuǎn)變成類別數(shù)據(jù)呢?

          一個(gè)解決辦法是對年齡范圍打標(biāo)簽,比如"adult", "young adult", "child"。實(shí)現(xiàn)該功能的最好方式是使用cut()函數(shù):

          這會對每個(gè)值打上標(biāo)簽。0到18歲的打上標(biāo)簽"child",18-25歲的打上標(biāo)簽"young adult",25到99歲的打上標(biāo)簽“adult”。

          注意到,該數(shù)據(jù)類型為類別變量,該類別變量自動(dòng)排好序了(有序的類別變量)。

          24. 更改顯示選項(xiàng)

          讓我們再來看一眼Titanic 數(shù)據(jù)集:

          注意到,Age列保留到小數(shù)點(diǎn)后1位,F(xiàn)are列保留到小數(shù)點(diǎn)后4位。如果你想要標(biāo)準(zhǔn)化,將顯示結(jié)果保留到小數(shù)點(diǎn)后2位呢?

          你可以使用set_option()函數(shù):

          set_option()函數(shù)中第一個(gè)參數(shù)為選項(xiàng)的名稱,第二個(gè)參數(shù)為Python格式化字符。可以看到,Age列和Fare列現(xiàn)在已經(jīng)保留小數(shù)點(diǎn)后兩位。注意,這并沒有修改基礎(chǔ)的數(shù)據(jù)類型,而只是修改了數(shù)據(jù)的顯示結(jié)果。

          你也可以重置任何一個(gè)選項(xiàng)為其默認(rèn)值:

          對于其它的選項(xiàng)也是類似的使用方法。

          25. Style a DataFrame

          上一個(gè)技巧在你想要修改整個(gè)jupyter notebook中的顯示會很有用。但是,一個(gè)更靈活和有用的方法是定義特定DataFrame中的格式化(style)。

          讓我們回到stocks這個(gè)DataFrame:

          我們可以創(chuàng)建一個(gè)格式化字符串的字典,用于對每一列進(jìn)行格式化。然后將其傳遞給DataFrame的style.format()函數(shù):

          注意到,Date列是month-day-year的格式,Close列包含一個(gè)$符號,Volume列包含逗號。

          我們可以通過鏈?zhǔn)秸{(diào)用函數(shù)來應(yīng)用更多的格式化:

          我們現(xiàn)在隱藏了索引,將Close列中的最小值高亮成紅色,將Close列中的最大值高亮成淺綠色。

          這里有另一個(gè)DataFrame格式化的例子:

          Volume列現(xiàn)在有一個(gè)漸變的背景色,你可以輕松地識別出大的和小的數(shù)值。

          最后一個(gè)例子:

          現(xiàn)在,Volumn列上有一個(gè)條形圖,DataFrame上有一個(gè)標(biāo)題。

          請注意,還有許多其他的選項(xiàng)你可以用來格式化DataFrame。

          -END-

          往期精彩推薦 --??


          -- 1、這個(gè)在線代碼編輯器,可以分享給任何人

          -- 2、Python 造假數(shù)據(jù),用Faker就夠了

          -- 3、在Python中玩轉(zhuǎn)Json數(shù)據(jù)




          --? 留下你的?“在看”?唄!

          ?

          瀏覽 66
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲国产97 | 蜜桃AV天堂 | 人妻无码中文字幕免费视频蜜桃 | 一区二区三区亚洲 | 91ThePorn国产 |