整理了 25 個 Pandas 實(shí)用技巧

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

1. 顯示已安裝的版本
輸入下面的命令查詢pandas版本:

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

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

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

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

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

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

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

如果你需要做的僅僅是將空格換成下劃線,那么更好的辦法是使用str.replace()方法,這是因?yàn)槟愣疾恍枰斎胨械牧忻?br>

上述三個函數(shù)的結(jié)果都一樣,可以更改列名使得列名中不含有空格:

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

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

4. 行序反轉(zhuǎn)

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

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

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

逗號之前的冒號表示選擇所有行,逗號之后的::-1表示反轉(zhuǎn)所有的列,這就是為什么country這一列現(xiàn)在在最右邊。
6. 通過數(shù)據(jù)類型選擇列

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

這包含了int和float型的列。

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

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

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

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

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

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

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

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

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

8. 減小DataFrame空間大小

可以看到它使用了304.KB。

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

通過將continent列讀取為category數(shù)據(jù)類型,我們進(jìn)一步地把DataFrame的空間大小縮小至2.3KB。
9. 按行從多個文件中構(gòu)建DataFrame

這是第二天的:

這是第三天的:

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

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

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

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

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

現(xiàn)在我們的DataFrame已經(jīng)有六列了。
11. 從剪貼板中創(chuàng)建DataFrame

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

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

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

需要注意的是,如果你想要你的工作在未來可復(fù)制,那么read_clipboard()并不值得推薦。
12. 將DataFrame劃分為兩個隨機(jī)的子集

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

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

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

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

或者"moives_2":

需要注意的是,這個方法在索引值不唯一的情況下不起作用。
13. 通過多種類型對DataFrame進(jìn)行過濾

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

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

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

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

這種方法能夠起作用是因?yàn)樵赑ython中,波浪號表示“not”操作。
14. 從DataFrame中篩選出數(shù)量最多的類別

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

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

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

這樣,在DataFrame中只剩下Drame, Comdey, Action這三種類型的電影了。
15. 處理缺失值

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

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


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

len(ufo)返回總行數(shù),我們將它乘以0.9,以告訴pandas保留那些至少90%的值不是缺失值的列。
16. 將一個字符串劃分成多個列

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

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

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

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

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

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

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

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

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

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

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

這將告訴我們沒定訂單的總價格和數(shù)量。
19. 將聚合結(jié)果與DataFrame進(jìn)行組合

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

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

比這個函數(shù)的輸入要小:

解決的辦法是使用transform()函數(shù),它會執(zhí)行相同的操作但是返回與輸入數(shù)據(jù)相同的形狀:

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

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

20. 選取行和列的切片

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

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

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

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

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

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

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

該DataFrame包含了與MultiIndexed Series一樣的數(shù)據(jù),不同的是,現(xiàn)在你可以用熟悉的DataFrame的函數(shù)對它進(jìn)行操作。
22. 創(chuàng)建數(shù)據(jù)透視表(pivot table)

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

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

這個結(jié)果展示了每一對類別變量組合后的記錄總數(shù)。
23. 將連續(xù)數(shù)據(jù)轉(zhuǎn)變成類別數(shù)據(jù)

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

這會對每個值打上標(biāo)簽。0到18歲的打上標(biāo)簽"child",18-25歲的打上標(biāo)簽"young adult",25到99歲的打上標(biāo)簽“adult”。
24. 更改顯示選項

注意到,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ù)中第一個參數(shù)為選項的名稱,第二個參數(shù)為Python格式化字符??梢钥吹?,Age列和Fare列現(xiàn)在已經(jīng)保留小數(shù)點(diǎn)后兩位。注意,這并沒有修改基礎(chǔ)的數(shù)據(jù)類型,而只是修改了數(shù)據(jù)的顯示結(jié)果。

對于其它的選項也是類似的使用方法。
25. Style a DataFrame

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

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

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

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

現(xiàn)在,Volumn列上有一個條形圖,DataFrame上有一個標(biāo)題。
零基礎(chǔ)學(xué) Python,請往看下嘛 送您價值 109 的視頻課 ?只需7天時間,跨進(jìn)Python編程大門,已有3800+加入 【基礎(chǔ)】0基礎(chǔ)入門python,24小時有人快速解答問題;
【提高】40多個項目實(shí)戰(zhàn),老手可以從真實(shí)場景中學(xué)習(xí)python;
【直播】不定期直播項目案例講解,手把手教你如何分析項目;
【分享】優(yōu)質(zhì)python學(xué)習(xí)資料分享,讓你在最短時間獲得有價值的學(xué)習(xí)資源;圈友優(yōu)質(zhì)資料或?qū)W習(xí)分享,會不時給予贊賞支持,希望每個優(yōu)質(zhì)圈友既能賺回加入費(fèi)用,也能快速成長,并享受分享與幫助他人的樂趣。
【人脈】收獲一群志同道合的朋友,并且都是python從業(yè)者
【價格】本著布道思想,只需 69元 加入一個能保證學(xué)習(xí)效果的良心圈子。【贈予】價值109元 0基礎(chǔ)入門在線課程,免費(fèi)送給圈友們,供鞏固 如果看到這里,說明你喜歡這篇文章,請轉(zhuǎn)發(fā)、點(diǎn)贊。 老鐵,三連支持一下,好嗎?↓↓↓
評論
圖片
表情
