也許大多數人都有在Excel中使用數據透視表的經歷,其實Pandas也提供了一個相似的功能,名爲pivot_table。雖然pivot_table很是有用,可是我發現爲了格式化輸出我所須要的內容,常常須要記住它的使用語法。因此,本文將重點解釋pandas中的函數pivot_table,並教你們如何使用它來進行數據分析。html
若是你對這個概念不熟悉,wikipedia上對它作了詳細的解釋。順便說一下,你知道微軟爲PivotTable(透視表)註冊了商標嗎?其實之前我也不知道。不用說,下面我將討論的透視表並非PivotTable。python
做爲一個額外的福利,我建立了一個總結pivot_table的簡單備忘單。你能夠在本文的最後找到它,我但願它可以對你有所幫助。若是它幫到了你,請告訴我。git
使用pandas中pivot_table的一個挑戰是,你須要確保你理解你的數據,並清楚地知道你想經過透視表解決什麼問題。其實,雖然pivot_table看起來只是一個簡單的函數,可是它可以快速地對數據進行強大的分析。github
在本文中,我將會跟蹤一個銷售渠道(也稱爲漏斗)。基本的問題是,一些銷售週期很長(能夠想一下「企業軟件」、「資本設備」等),而管理者想更詳細地瞭解它一全年的狀況。函數
典型的問題包括:工具
不少公司將會使用CRM工具或者其餘銷售使用的軟件來跟蹤此過程。雖然他們可能擁有有效的工具對數據進行分析,但確定有人須要將數據導出到Excel,並使用一個透視表工具來總結這些數據。url
使用Pandas透視表將是一個不錯的選擇,應爲它有如下優勢:spa
首先,讓咱們搭建所需的環境。excel
若是你想跟隨我繼續下去,那麼能夠下載這個Excel文件。code
1
2
|
import pandas as pd
import numpy as np
|
版本提醒
由於Pivot_table API已經隨着時間有所改變,因此爲了使本文中示例代碼可以正常工做,請確保你安裝了最近版本的Pandas(>0.15)。本文示例還用到了category數據類型,而它也須要確保是最近版本。
首先,將咱們銷售渠道的數據讀入到數據幀中。
1
2
|
df = pd.read_excel("../in/sales-funnel.xlsx")
df.head()
|
爲方便起見,咱們將上表中「Status」列定義爲category,並按咱們想要的查看方式設置順序。
其實,並不嚴格要求這樣作,但這樣作可以在分析數據的整個過程當中,幫助咱們保持所想要的順序。
1
2
|
df["Status"] = df["Status"].astype("category")
df["Status"].cat.set_categories(["won","pending","presented","declined"],inplace=True)
|
既然咱們創建數據透視表,我以爲最容易的方法就是一步一個腳印地進行。添加項目和檢查每一步來驗證你正一步一步獲得指望的結果。爲了查看什麼樣的外觀最能知足你的須要,就不要懼怕處理順序和變量的繁瑣。
最簡單的透視表必須有一個數據幀和一個索引。在本例中,咱們將使用「Name(名字)」列做爲咱們的索引。
1
|
pd.pivot_table(df,index=["Name"])
|
此外,你也能夠有多個索引。實際上,大多數的pivot_table參數能夠經過列表獲取多個值。
1
|
pd.pivot_table(df,index=["Name","Rep","Manager"])
|
這樣頗有趣但並非特別有用。咱們可能想作的是經過將「Manager」和「Rep」設置爲索引來查看結果。要實現它其實很簡單,只須要改變索引就能夠。
1
|
pd.pivot_table(df,index=["Manager","Rep"])
|
能夠看到,透視表比較智能,它已經開始經過將「Rep」列和「Manager」列進行對應分組,來實現數據聚合和總結。那麼如今,就讓咱們共同看一下數據透視表能夠爲咱們作些什麼吧。
爲此,「Account」和「Quantity」列對於咱們來講並沒什麼用。因此,經過利用「values」域顯式地定義咱們關心的列,就能夠實現移除那些不關心的列。
1
|
pd.pivot_table(df,index=["Manager","Rep"],values=["Price"])
|
「Price」列會自動計算數據的平均值,可是咱們也能夠對該列元素進行計數或求和。要添加這些功能,使用aggfunc和np.sum就很容易實現。
1
|
pd.pivot_table(df,index=["Manager","Rep"],values=["Price"],aggfunc=np.sum)
|
aggfunc能夠包含不少函數,下面就讓咱們嘗試一種方法,即便用numpy中的函數mean和len來進行計數。
1
|
pd.pivot_table(df,index=["Manager","Rep"],values=["Price"],aggfunc=[np.mean,len])
|
若是咱們想經過不一樣產品來分析銷售狀況,那麼變量「columns」將容許咱們定義一個或多個列。
列vs.值
我認爲pivot_table中一個使人困惑的地方是「columns(列)」和「values(值)」的使用。記住,變量「columns(列)」是可選的,它提供一種額外的方法來分割你所關心的實際值。然而,聚合函數aggfunc最後是被應用到了變量「values」中你所列舉的項目上。
1
2
|
pd.pivot_table(df,index=["Manager","Rep"],values=["Price"],
columns=["Product"],aggfunc=[np.sum])
|
然而,非數值(NaN)有點使人分心。若是想移除它們,咱們可使用「fill_value」將其設置爲0。
1
2
|
pd.pivot_table(df,index=["Manager","Rep"],values=["Price"],
columns=["Product"],aggfunc=[np.sum],fill_value=0)
|
其實,我以爲添加「Quantity」列將對咱們有所幫助,因此將「Quantity」添加到「values」列表中。
1
2
|
pd.pivot_table(df,index=["Manager","Rep"],values=["Price","Quantity"],
columns=["Product"],aggfunc=[np.sum],fill_value=0)
|
有趣的是,你能夠將幾個項目設置爲索引來得到不一樣的可視化表示。下面的代碼中,咱們將「Product」從「columns」中移除,並添加到「index」變量中。
1
2
|
pd.pivot_table(df,index=["Manager","Rep","Product"],
values=["Price","Quantity"],aggfunc=[np.sum],fill_value=0)
|
對於這個數據集,這種顯示方式看起來更有意義。不過,若是我想查看一些總和數據呢?「margins=True」就能夠爲咱們實現這種功能。
1
2
3
|
pd.pivot_table(df,index=["Manager","Rep","Product"],
values=["Price","Quantity"],
aggfunc=[np.sum,np.mean],fill_value=0,margins=True)
|
下面,讓咱們以更高的管理者角度來分析此渠道。根據咱們前面對category的定義,注意如今「Status」是如何排序的。
1
2
|
pd.pivot_table(df,index=["Manager","Status"],values=["Price"],
aggfunc=[np.sum],fill_value=0,margins=True)
|
一個很方便的特性是,爲了對你選擇的不一樣值執行不一樣的函數,你能夠向aggfunc傳遞一個字典。不過,這樣作有一個反作用,那就是必須將標籤作的更加簡潔才行。
1
2
|
pd.pivot_table(df,index=["Manager","Status"],columns=["Product"],values=["Quantity","Price"],
aggfunc={"Quantity":len,"Price":np.sum},fill_value=0)
|
此外,你也能夠提供一系列的聚合函數,並將它們應用到「values」中的每一個元素上。
1
2
3
|
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)的數據,能夠這樣:
1
|
table.query('Manager == ["Debra Henley"]')
|
咱們能夠查看全部的暫停(pending)和成功(won)的交易,代碼以下所示:
1
|
table.query('Status == ["pending","won"]')
|
這是pivot_table中一個很強大的特性,因此一旦你獲得了你所須要的pivot_table格式的數據,就不要忘了此時你就擁有了pandas的強大威力。
The full notebook is available if you would like to save it as a reference.
若是你想將其保存下來做爲參考,那麼這裏提供完整的筆記。
爲了試圖總結全部這一切,我已經建立了一個備忘單,我但願它可以幫助你記住如何使用pandas的pivot_table。