當前位置:
首頁 > 知識 > 你可能不知道的10個Python Pandas的技巧和特性

你可能不知道的10個Python Pandas的技巧和特性


Pandas是一個基礎庫,用於分析、數據處理和數據科學。它是一個龐大的項目,有大量的選擇和奧秘。


本教程將以Buzzfeed清單體介紹一些使用較少但慣用的Pandas功能,這些功能為你的代碼提供更好的可讀性、通用性和速度。


如果你對Python Pandas庫的核心概念感到滿意,那麼希望你能在本文中找到一兩個以前沒有遇到過的技巧。(如果你剛開始學習該庫,Pandas 10分鐘是一個很好的開始。)


注意:

本文中的示例用Pandas版本0.23.2和Python 3.66進行測試。不過,它們應該也適用於舊版本。


1.  解釋器啟動時的配置選項和設置


你可能曾經遇到過Pandas豐富的選項和設置系統。


在解釋器啟動時設置定製的Pandas選項可以節省大量生產力,尤其是在腳本環境中工作。你可以使用pd.set_option()通過Python或ipython啟動文件配置你的核心內容。


選項使用點標記,如pd.set_option("display.max_colwidth", 25),這非常適用於一個嵌套的選項字典:



如果你啟動一個解釋器會話,將看到啟動腳本中的所有內容都已執行,並且自動為你導入Pandas和選項套件:



讓我們通過UCI機器學習存儲庫上的一些有關鮑魚的數據來演示啟動文件中設置的格式。數據將在第14行截斷,浮點數的精度為4位:


稍後還會在其他示例中出現這個數據集。



2. 用Pandas測試模塊製作Toy數據結構


在Pandas測試模塊中有很多隱藏的便捷功能,它們用於快速建立擬現實Series和DataFrames:



大約有30個,你可以通過調用模塊對象上的dir()來查看完整的列表。這裡有幾個:



這些可以用於基準測試、測試斷言、以及對你不太熟悉的Pandas方法的實驗。


3. 利用Accessor方法

也許你聽說過術語

accessor

,它有點像getter(雖然在Python中很少使用getter和setter)。為了我們的目的,你可以將Pandas accessor看作一個屬性,作為其它方法的介面。


Pandas Series有三個:



是的,上面的定義很有意思,讓我們先看幾個例子,然後討論內部結構。


.cat是用於分類數據的,.str是針對字元串(對象)數據的,而.dt是用於類似於日期時間的數據。讓我們從.str開始:設想你有一些原始的城市/州/郵編數據,作為Pandas Series中的一個欄位。


Pandas字元串方法是矢量化的,這意味著它們對整個數組進行操作,而沒有顯式的for循環:



舉個更複雜的例子,假設你希望將城市/州/郵編三個要素整齊地分到DataFrame欄位中。


可以將正則表達式傳遞給.str.extract(),以「提取」Series中每個單元格的部分。在.str.extract()中,.str是accessor,.str.extract()是一個accessor方法:


這也說明了所謂的方法鏈,其中.str.extract(regex)在addr.str.replace(".", "")的結果上被調用,該方法清理了句點的使用,從而得到一個好的雙字元狀態縮寫。


稍微了解一下這些accessor方法是如何工作的,作為你應該首先使用它們,而不是像addr.apply(re.findall, ...)這樣的東西的原因,這是很有幫助的。


每個accessor本身就是一個真正的Python類:




  • .str 映射到 StringMethods.



  • .dt 映射到 CombinedDatetimelikeProperties.



  •  .cat 到 CategoricalAccessor.


然後使用CachedAccessor將這些獨立類「附加」到Series類。當類用CachedAccessor包裝時,會發生一點魔法。


CachedAccessor的靈感來自「緩存屬性」設計:每個實例只計算一次屬性,然後用普通屬性替換。它通過重載.__get__()方法來實現這一點,該方法是Python的描述符協議的一部分。


注意:

如果您想了解更多關於其工作原理的內部信息,請參閱Python Descriptor HOWTO和這篇關於緩存屬性設計的文章。Python 3還引入了 functools.lru_cache(),它提供了類似的功能。


第二個accessor, .dt是用於類似日期時間的數據。它在技術上屬於Pandas的DatetimeIndex,如果在Series上調用,它首先轉換為DatetimeIndex :



第三個accessor ,.cat,只用於分類數據,你很快將在它自己的部分中看到。


4.從組件列創建DatetimeIndex


說到類似datetime的數據,如上面的daterng,可以從多個組成列創建一個Pandas DatetimeIndex,這些組成列共同構成一個日期或日期時間:



最後,你可以刪除舊的單個列並轉換為Series:


傳遞DataFrame的直覺是,DataFrame類似於Python字典,其中列名是鍵,各個列(Series)是字典值。這就是為什麼pd.to_datetime(df[datecols].to_dict(orient="list"))在這種情況下也會起作用的原因。這反映了Python的datetime.datetime的構造,你可以在其中傳遞關鍵字參數,如datetime.datetime(year=2000, month=1, day=15, hour=10)。


5. 使用分類數據節省時間和空間


Pandas的一個強大特性是它的分類dtype。


即使你並不總是使用RAM中的千兆位元組數據,你也可能遇到這樣的情況,即直接操作大型DataFrame似乎掛起超過幾秒鐘。


Pandas object dtype通常是轉換到類別數據的最佳候選。(object是Python str、異構數據類型或「其他」類型的容器。)字元串在內存中佔用大量空間:



注意

我使用sys.getsizeof()來顯示序列中每個單獨的值佔用的內存。請記住,這些是Python對象,這些對象在一開始就有一些開銷。(sys.getsizeof("")將返回49位元組。)

還有colors.memory_usage(),它總結了內存使用情況,並依賴於底層NumPy數組的.nbytes屬性。不要太拘泥於這些細節:重要的是類型轉換導致的相對內存使用,正如您接下來將看到的。


現在,如果我們把上面的獨特顏色映射到一個佔用更少空間的整數中呢?下面是一個簡單的實現:



注意:

另一種方法是Pandas的pd.factorize(colors):



無論哪種方式,都是將對象編碼為枚舉類型(分類變數)。

你會立刻注意到,與object dtype使用完整字元串相比,內存使用量幾乎減少了一半。


在accessor一節中,我提到了.cat(分類)accessor。上面的mapper粗略的說明Pandas的Categoricaldtype內部正在發生:


「Categorical的內存使用與類別的數量加上數據的長度成正比。相反,對象dtype是數據長度的常數倍。」(來源)


在上面的colors中,每一個唯一值(類別)都有2個值的比率:



結果,從轉換到分類的內存節省是好的,但不是很大:



但是,如果用大量的數據和很少的唯一值(考慮人口統計或字母測試分數的數據)來誇大上述比例,則所需的內存減少超過10倍:


另一個好處是計算效率也得到了提升:對於分類Series,字元串操作是在.cat.categories屬性上執行的,而不是在Series的每個原始元素上執行的。


換言之,操作在每一個唯一類別進行,並將結果映射回值。分類數據有一個.cat accessor ,它是一扇窗用於操作屬性和方法來處理類別:



事實上,您可以手動再現類似於上面的示例:



為了精確地模擬早期手動輸出,你需要做的是重新排序代碼:



注意,dType是NumPy的int8,一個8位有符號整數,可以取值為-127到128。(只需要一個位元組來表示內存中的值。在內存使用方面,64位有符號ints將被過度使用。)我們的粗略示例默認情況下得到int64數據,而Pandas足夠聰明,能夠將分類數據向下轉換到儘可能小的數字dtype。


.cat的大多數屬性與查看和操作底層類別本身有關:



不過,也有一些注意事項。分類數據一般不那麼靈活。例如,如果插入以前沒出現過的值,則需要先將此值添加到..categories容器中:



如果你計劃設置值或修正數據而不是派生新的計算,則Categorical類型可能不那麼靈活。


未完,6-10條見本日推送第二篇文章。





英文原文:https://realpython.com/python-pandas-tricks/


譯者:張新英



喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 Python程序員 的精彩文章:

為什麼有的領導者希望他們的明星員工離開
Python模塊和包初探

TAG:Python程序員 |