當前位置: 妍妍網 > 碼農

使用Pandas 玩轉透視表(pivot_table)

2024-02-27碼農

來源:pbpython 編譯: 伯樂線上 - PyPer

介紹

也許大多數人都有在Excel中使用數據透視表的經歷,其實Pandas也提供了一個類似的功能,名為 pivot_table。雖然pivot_table非常有用,但是我發現為了格式化輸出我所需要的內容,經常需要記住它的使用語法。所以,本文將重點解釋pandas中的函式 pivot_table,並教大家如何使用它來進行數據分析。

如果你對這個概念不熟悉,維基百科上對它做了詳細的解釋。順便說一下,你知道微軟為PivotTable(透視表)註冊了商標嗎?其實以前我也不知道。不用說,下面我將討論的透視表並不是PivotTable。

作為一個額外的福利,我建立了一個總結pivot_table的簡單備忘單。你可以在本文的最後找到它,我希望它能夠對你有所幫助。如果它幫到了你,請告訴我。

數據

使用pandas中pivot_table的一個挑戰是,你需要確保你理解你的數據,並清楚地知道你想透過透視表解決什麽問題。其實,雖然pivot_table看起來只是一個簡單的函式,但是它能夠快速地對數據進行強大的分析。

在本文中,我將會跟蹤一個銷售渠道(也稱為漏鬥)。基本的問題是,一些銷售周期很長(可以想一下「企業軟體」、「資本裝置」等),而管理者想更詳細地了解它一整年的情況。

典型的問題包括:

  • 本渠道收入是多少?

  • 渠道的產品是什麽?

  • 誰在什麽階段有什麽產品?

  • 我們年底前結束交易的可能性有多大?

  • 很多公司將會使用CRM工具或者其他銷售使用的軟體來跟蹤此過程。雖然他們可能擁有有效的工具對數據進行分析,但肯定有人需要將數據匯出到Excel,並使用一個透視表工具來總結這些數據。

    使用Pandas透視表將是一個不錯的選擇,應為它有以下優點:

  • 更快(一旦設定之後)

  • 自行說明(透過檢視程式碼,你將知道它做了什麽)

  • 易於生成報告或電子信件

  • 更靈活,因為你可以定義客製的聚合函式

  • Read in the data

    首先,讓我們搭建所需的環境。

    如果你想跟隨我繼續下去,那麽可以下載這個Excel檔。

    import pandas as pd

    import numpy as np

    版本提醒

    因為Pivot_table API已經隨著時間有所改變,所以為了使本文中範例程式碼能夠正常工作,請確保你安裝了最近版本的Pandas(>0.15)。本文範例還用到了category數據型別,而它也需要確保是最近版本。

    首先,將我們銷售渠道的數據讀入到數據幀中。

    df = pd . read_excel ( "../in/sales-funnel.xlsx" )

    df . head ()

    為方便起見,我們將上表中「Status」列定義為category,並按我們想要的檢視方式設定順序。

    其實,並不嚴格要求這樣做,但這樣做能夠在分析數據的整個過程中,幫助我們保持所想要的順序。

    df [ "Status" ] = df [ "Status" ]. astype ( "category" )

    df [ "Status" ]. cat . set_categories ([ "won" , "pending" , "presented" , "declined" ], inplace = True )

    處理數據

    既然我們建立數據透視表,我覺得最容易的方法就是一步一個腳印地進行。添加計畫和檢查每一步來驗證你正一步一步得到期望的結果。為了檢視什麽樣的外觀最能滿足你的需要,就不要害怕處理順序和變量的繁瑣。

    最簡單的透視表必須有一個數據幀和一個索引。在本例中,我們將使用「Name(名字)」列作為我們的索引。

    pd.pivot_table(df,index=["Name"])

    此外,你也可以有多個索引。實際上,大多數的pivot_table參數可以透過列表獲取多個值

    pd.pivot_table(df,index=["Name","Rep","Manager"])

    這樣很有趣但並不是特別有用。我們可能想做的是透過將「Manager」和「Rep」設定為索引來檢視結果。

    要實作它其實很簡單,只需要改變索引就可以。

    pd.pivot_table(df,index=["Manager","Rep"])

    可以看到,透視表比較智慧,它已經開始透過將「Rep」列和「Manager」列進行對應分組,來實作數據聚合和總結。那麽現在,就讓我們共同看一下數據透視表可以為我們做些什麽吧。

    為此,「Account」和「Quantity」列對於我們來說並沒什麽用。所以,透過利用「values」域顯式地定義我們關心的列,就可以實作移除那些不關心的列。

    pd.pivot_table(df,index=["Manager","Rep"],values=["Price"])

    「Price」列會自動計算數據的平均值,但是我們也可以對該列元素進行計數或求和。要添加這些功能,使用aggfunc和np.sum就很容易實作。

    pd.pivot_table(df,index=["Manager","Rep"],values=["Price"],aggfunc=np.sum)


    aggfunc可以包含很多函式,下面就讓我們嘗試一種方法,即使用numpy中的函式mean和len來進行計數。

    pd.pivot_table(df,index=["Manager","Rep"],values=["Price"],aggfunc=[np.mean,len])

    如果我們想透過不同產品來分析銷售情況,那麽變量「columns」將允許我們定義一個或多個列。

    列vs.值

    我認為pivot_table中一個令人困惑的地方是「columns(列)」和「values(值)」的使用。記住,變量「columns(列)」是可選的,它提供一種額外的方法來分割你所關心的實際值。然而,聚合函式aggfunc最後是被套用到了變量「values」中你所列舉的計畫上。

    pd . pivot_table ( df , index = [ "Manager" , "Rep" ], values = [ "Price" ],

    columns = [ "Product" ], aggfunc = [ np . sum ])

    然而,非數值(NaN)有點令人分心。如果想移除它們,我們可以使用「fill_value」將其設定為0。

    pd . pivot_table ( df , index = [ "Manager" , "Rep" ], values = [ "Price" ],

    columns = [ "Product" ], aggfunc = [ np . sum ], fill_value = 0 )

    其實,我覺得添加「Quantity」列將對我們有所幫助,所以將「Quantity」添加到「values」列表中。

    pd . pivot_table ( df , index = [ "Manager" , "Rep" ], values = [ "Price" , "Quantity" ],

    columns = [ "Product" ], aggfunc = [ np . sum ], fill_value = 0 )

    pd . pivot_table ( df , index = [ "Manager" , "Rep" , "Product" ],

    values = [ "Price" , "Quantity" ], aggfunc = [ np . sum ], fill_value = 0 )

    對於這個數據集,這種顯示方式看起來更有意義。不過,如果我想檢視一些總和數呢?「margins=True」就可以為我們實作這種功能。

    pd . pivot_table ( df , index = [ "Manager" , "Rep" , "Product" ],

    values = [ "Price" , "Quantity" ],

    aggfunc = [ np . sum , np . mean ], fill_value = 0 , margins = True )

    下面,讓我們以更高的管理者角度來分析此渠道。根據我們前面對category的定義,註意現在「Status」是如何排序的。

    pd . pivot_table ( df , index = [ "Manager" , "Status" ], values = [ "Price" ],

    aggfunc = [ np . sum ], fill_value = 0 , margins = True )

    一個很方便的特性是,為了對你選擇的不同值執行不同的函式,你可以向aggfunc傳遞一個字典。不過,這樣做有一個副作用,那就是必須將標簽做的更加簡潔才行。

    pd . pivot_table ( df , index = [ "Manager" , "Status" ], columns = [ "Product" ], values = [ "Quantity" , "Price" ],

    aggfunc = { "Quantity" : len , "Price" : np . sum }, fill_value = 0 )

    此外,你也可以提供一系列的聚合函式,並將它們套用到「values」中的每個元素上。

    table = pd . pivot_table ( df , index = [ "Manager" , "Status" ], columns = [ "Product" ], values = [ "Quantity" , "Price" ],

    aggfunc = { "Quantity" : len , "Price" : [ np . sum , np . mean ]}, fill_value = 0 )

    table

    也許,同一時間將這些東西全都放在一起會有點令人望而生畏,但是一旦你開始處理這些數據,並一步一步地添加新計畫,你將能夠領略到它是如何工作的。我一般的經驗法則是,一旦你使用多個「grouby」,那麽你需要評估此時使用透視表是否是一種好的選擇。

    高級透視表過濾

    一旦你生成了需要的數據,那麽數據將存在於數據幀中。所以,你可以使用自訂的標準數據幀函式來對其進行過濾。

    如果你只想檢視一個管理者(例如Debra Henley)的數據,可以這樣:

    table.query('Manager == ["Debra Henley"]')

    我們可以檢視所有的暫停(pending)和成功(won)的交易,程式碼如下所示:

    table.query('Status == ["pending","won"]')

    這是pivot_table中一個很強大的特性,所以一旦你得到了你所需要的pivot_table格式的數據,就不要忘了此時你就擁有了pandas的強大威力。

    如果你想將其保存下來作為參考,那麽這裏提供完整的筆記:http://nbviewer.ipython.org/url/pbpython.com/extras/Pandas-Pivot-Table-Explained.ipynb

    數據下載地址:http://pbpython.com/extras/sales-funnel.xlsx

    備忘單

    為了試圖總結所有這一切,我已經建立了一個備忘單,我希望它能夠幫助你記住如何使用pandas的pivot_table。

    加入知識星球【我們談論數據科學】

    600+小夥伴一起學習!