從剪貼板中創(chuàng)建DataFrame
假設(shè)你將一些數(shù)據(jù)儲(chǔ)存在Excel或者Google Sheet中,你又想要盡快地將他們讀取至DataFrame中。你需要選擇這些數(shù)據(jù)并復(fù)制至剪貼板。然后,你可以使用read_clipboard()函數(shù)將他們讀取至DataFrame中:

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

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

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

需要注意的是,如果你想要你的工作在未來可復(fù)制,那么read_clipboard()并不值得推薦。
將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í)和嘗試。
多種類型過濾DataFrame
讓我們先看一眼movies這個(gè)DataFrame:
In[60]: movies.head() Out[60]:

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

比如我們想要對(duì)該DataFrame進(jìn)行過濾,我們只想顯示genre為Action或者Drama或者Western的電影,我們可以使用多個(gè)條件,以"or"符號(hào)分隔:
In[62]: movies[(movies.genre=='Action')| (movies.genre=='Drama')| (movies.genre== 'Western')].head() Out[62]:

但是,你實(shí)際上可以使用isin()函數(shù)將代碼寫得更加清晰,將genres列表傳遞給該函數(shù):
In[63]: movies[movies.genre.isin(['Action','Drama','Western'])].head() Out[63]:

如果你想要進(jìn)行相反的過濾,也就是你將吧剛才的三種類型的電影排除掉,那么你可以在過濾條件前加上破浪號(hào):
In[64]: movies[~movies.genre.isin(['Action', 'Drama','Western'])].head() Out[64]:

這種方法能夠起作用是因?yàn)樵?a href="http://m.sdkjxy.cn/tags/python/" target="_blank">Python中,波浪號(hào)表示“not”操作。
DataFrame篩選數(shù)量最多類別
假設(shè)你想要對(duì)movies這個(gè)DataFrame通過genre進(jìn)行過濾,但是只需要前3個(gè)數(shù)量最多的genre。
我們對(duì)genre使用value_counts()函數(shù),并將它保存成counts(type為Series):

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

事實(shí)上我們?cè)谠揝eries中需要的是索引:

最后,我們將該索引傳遞給isin()函數(shù),該函數(shù)會(huì)把它當(dāng)成genre列表:
In[68]: movies[movies.genre.isin(counts.nlargest(3).index)].head() Out[68]:

這樣,在DataFrame中只剩下Drame, Comdey, Action這三種類型的電影了。
處理缺失值
讓我們來看一看UFO sightings這個(gè)DataFrame:

你將會(huì)注意到有些值是缺失的。
為了找出每一列中有多少值是缺失的,你可以使用isna()函數(shù),然后再使用sum():

isna()會(huì)產(chǎn)生一個(gè)由True和False組成的DataFrame,sum()會(huì)將所有的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%的值不是缺失值的列。
一個(gè)字符串劃分成多列
我們先創(chuàng)建另一個(gè)新的示例DataFrame:

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

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

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

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

Series擴(kuò)展成DataFrame
讓我們創(chuàng)建一個(gè)新的示例DataFrame:

這里有兩列,第二列包含了Python中的由整數(shù)元素組成的列表。
如果我們想要將第二列擴(kuò)展成DataFrame,我們可以對(duì)那一列使用apply()函數(shù)并傳遞給Series constructor:

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

對(duì)多個(gè)函數(shù)進(jìn)行聚合
讓我們來看一眼從Chipotle restaurant chain得到的orders這個(gè)DataFrame:
In[82]: orders.head(10) Out[82]:

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

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

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

這將告訴我們沒定訂單的總價(jià)格和數(shù)量。
聚合結(jié)果與DataFrame組合
讓我們?cè)倏匆谎踥rders這個(gè)DataFrame:
In[86]: orders.head(10) Out[86]:

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

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

比這個(gè)函數(shù)的輸入要?。?/p>

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

我們將這個(gè)結(jié)果存儲(chǔ)至DataFrame中新的一列:
In[91]: orders['total_price']= total_price orders.head(10) Out[91]:

你可以看到,每個(gè)訂單的總價(jià)格在每一行中顯示出來了。
這樣我們就能方便地甲酸每個(gè)訂單的價(jià)格占該訂單的總價(jià)格的百分比:
In[92]: orders['percent_of_total']=orders.item_price/orders.total_price orders.head(10) In[92]:

選取行和列的切片
讓我們看一眼另一個(gè)數(shù)據(jù)集:
In[93]: titanic.head() Out[93]:

這就是著名的Titanic數(shù)據(jù)集,它保存了Titanic上乘客的信息以及他們是否存活。
如果你想要對(duì)這個(gè)數(shù)據(jù)集做一個(gè)數(shù)值方面的總結(jié),你可以使用describe()函數(shù):

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

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

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

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

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

該結(jié)果展示了由Sex和Passenger Class聯(lián)合起來的存活率。它存儲(chǔ)為一個(gè)MultiIndexed Series,也就是說它對(duì)實(shí)際數(shù)據(jù)有多個(gè)索引層級(jí)。
這使得該數(shù)據(jù)難以讀取和交互,因此更為方便的是通過unstack()函數(shù)將MultiIndexed Series重塑成一個(gè)DataFrame:

該DataFrame包含了與MultiIndexed Series一樣的數(shù)據(jù),不同的是,現(xiàn)在你可以用熟悉的DataFrame的函數(shù)對(duì)它進(jìn)行操作。
創(chuàng)建數(shù)據(jù)透視表
如果你經(jīng)常使用上述的方法創(chuàng)建DataFrames,你也許會(huì)發(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é)果展示了每一對(duì)類別變量組合后的記錄總數(shù)。
連續(xù)數(shù)據(jù)轉(zhuǎn)類別數(shù)據(jù)
讓我們來看一下Titanic數(shù)據(jù)集中的Age那一列:

它現(xiàn)在是連續(xù)性數(shù)據(jù),但是如果我們想要將它轉(zhuǎn)變成類別數(shù)據(jù)呢?
一個(gè)解決辦法是對(duì)年齡范圍打標(biāo)簽,比如"adult", "young adult", "child"。實(shí)現(xiàn)該功能的最好方式是使用cut()函數(shù):

這會(huì)對(duì)每個(gè)值打上標(biāo)簽。0到18歲的打上標(biāo)簽"child",18-25歲的打上標(biāo)簽"young adult",25到99歲的打上標(biāo)簽“adult”。
注意到,該數(shù)據(jù)類型為類別變量,該類別變量自動(dòng)排好序了(有序的類別變量)。
Style a DataFrame
上一個(gè)技巧在你想要修改整個(gè)jupyter notebook中的顯示會(huì)很有用。但是,一個(gè)更靈活和有用的方法是定義特定DataFrame中的格式化(style)。
讓我們回到stocks這個(gè)DataFrame:

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

注意到,Date列是month-day-year的格式,Close列包含一個(gè)$符號(hào),Volume列包含逗號(hào)。
我們可以通過鏈?zhǔn)秸{(diào)用函數(shù)來應(yīng)用更多的格式化:

我們現(xiàn)在隱藏了索引,將Close列中的最小值高亮成紅色,將Close列中的最大值高亮成淺綠色。
這里有另一個(gè)DataFrame格式化的例子:

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

現(xiàn)在,Volumn列上有一個(gè)條形圖,DataFrame上有一個(gè)標(biāo)題。
請(qǐng)注意,還有許多其他的選項(xiàng)你可以用來格式化DataFrame。
額外技巧
Profile a DataFrame
假設(shè)你拿到一個(gè)新的數(shù)據(jù)集,你不想要花費(fèi)太多力氣,只是想快速地探索下。那么你可以使用pandas-profiling這個(gè)模塊。
在你的系統(tǒng)上安裝好該模塊,然后使用ProfileReport()函數(shù),傳遞的參數(shù)為任何一個(gè)DataFrame。它會(huì)返回一個(gè)互動(dòng)的HTML報(bào)告:
第一部分為該數(shù)據(jù)集的總覽,以及該數(shù)據(jù)集可能出現(xiàn)的問題列表
第二部分為每一列的總結(jié)。你可以點(diǎn)擊"toggle details"獲取更多信息
第三部分顯示列之間的關(guān)聯(lián)熱力圖
第四部分為缺失值情況報(bào)告
第五部分顯示該數(shù)據(jù)及的前幾行
使用示例如下(只顯示第一部分的報(bào)告):

原文鏈接:
https://nbviewer.jupyter.org/github/justmarkham/pandas-videos/blob/master/top_25_pandas_tricks.ipynb
-
函數(shù)
+關(guān)注
關(guān)注
3文章
4423瀏覽量
67884 -
機(jī)器學(xué)習(xí)
+關(guān)注
關(guān)注
67文章
8567瀏覽量
137277
原文標(biāo)題:這 25 個(gè) Pandas 實(shí)用技巧你都會(huì)嗎
文章出處:【微信號(hào):DBDevs,微信公眾號(hào):數(shù)據(jù)分析與開發(fā)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
Python AI 數(shù)字化實(shí)戰(zhàn):從 Pandas 自動(dòng)化到 DeepSeek “星邏系統(tǒng)”開發(fā),無密
onsemi FDP51N25與FDPF51N25 MOSFET深度解析
25W單輸出開關(guān)電源EPS - 25系列:技術(shù)剖析與設(shè)計(jì)考量
深入解析Microchip 25AA128/25LC128 128K SPI總線串行EEPROM
W25Q128JVSIM與GD25Q128ESIGR引腳兼容分析
便攜式近紅外光譜儀選購指南:5個(gè)關(guān)鍵參數(shù)與實(shí)用技巧
超聲波清洗機(jī)的工作原理與實(shí)用技巧全解析
便攜式礦物地物光譜儀選購指南:關(guān)鍵指標(biāo)與實(shí)用技巧揭秘
高效管理Kubernetes集群的實(shí)用技巧
DP-25差分探頭的介紹與注意事項(xiàng)
W25X16W25X32\W25X64 數(shù)據(jù)手冊(cè)
成功使用工業(yè)化超聲波清洗設(shè)備的七個(gè)實(shí)用技巧
泰克示波器MSO58B光標(biāo)橫豎切換操作指南與實(shí)用技巧
Altium Designer AD 25 軟件安裝包下載
【Java開發(fā)必備】IntelliJ IDEA數(shù)據(jù)庫功能進(jìn)階指南:9個(gè)JetBrains工程師私藏技巧
25個(gè)Pandas實(shí)用技巧
評(píng)論