天天看點

Pandas透視表(pivot_table)詳解

轉載于:https://www.cnblogs.com/onemorepoint/p/8425300.html

介紹

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

如果你對這個概念不熟悉,wikipedia上對它做了詳細的解釋。順便說一下,你知道微軟為PivotTable(透視表)注冊了商标嗎?其實以前我也不知道。不用說,下面我将讨論的透視表并不是PivotTable。

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

資料

使用pandas中pivot_table的一個挑戰是,你需要確定你了解你的資料,并清楚地知道你想通過透視表解決什麼問題。其實,雖然pivot_table看起來隻是一個簡單的函數,但是它能夠快速地對資料進行強大的分析。

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

典型的問題包括:

  • 本管道收入是多少?
  • 管道的産品是什麼?
  • 誰在什麼階段有什麼産品?
  • 我們年底前結束交易的可能性有多大?

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

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

  • 更快(一旦設定之後)
  • 自行說明(通過檢視代碼,你将知道它做了什麼)
  • 易于生成報告或電子郵件
  • 更靈活,因為你可以定義定制的聚合函數

Read in the data

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

如果你想跟随我繼續下去,那麼可以下載下傳這個Excel檔案。

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()

Pandas透視表(pivot_table)詳解

為友善起見,我們将上表中“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"])
Pandas透視表(pivot_table)詳解

此外,你也可以有多個索引。實際上,大多數的pivot_table參數可以通過清單擷取多個值。

1 pd.pivot_table(df,index=["Name","Rep","Manager"])
Pandas透視表(pivot_table)詳解

這樣很有趣但并不是特别有用。我們可能想做的是通過将“Manager”和“Rep”設定為索引來檢視結果。要實作它其實很簡單,隻需要改變索引就可以。

1 pd.pivot_table(df,index=["Manager","Rep"])
Pandas透視表(pivot_table)詳解

可以看到,透視表比較智能,它已經開始通過将“Rep”列和“Manager”列進行對應分組,來實作資料聚合和總結。那麼現在,就讓我們共同看一下資料透視表可以為我們做些什麼吧。

為此,“Account”和“Quantity”列對于我們來說并沒什麼用。是以,通過利用“values”域顯式地定義我們關心的列,就可以實作移除那些不關心的列。

1 pd.pivot_table(df,index=["Manager","Rep"],values=["Price"])
Pandas透視表(pivot_table)詳解

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

1 pd.pivot_table(df,index=["Manager","Rep"],values=["Price"],aggfunc=np.sum)
Pandas透視表(pivot_table)詳解

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

1 pd.pivot_table(df,index=["Manager","Rep"],values=["Price"],aggfunc=[np.mean,len])
Pandas透視表(pivot_table)詳解

如果我們想通過不同産品來分析銷售情況,那麼變量“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])

Pandas透視表(pivot_table)詳解

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

1

2

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

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

Pandas透視表(pivot_table)詳解

其實,我覺得添加“Quantity”列将對我們有所幫助,是以将“Quantity”添加到“values”清單中。

1

2

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

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

Pandas透視表(pivot_table)詳解

有趣的是,你可以将幾個項目設定為索引來獲得不同的可視化表示。下面的代碼中,我們将“Product”從“columns”中移除,并添加到“index”變量中。

1

2

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

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

Pandas透視表(pivot_table)詳解

對于這個資料集,這種顯示方式看起來更有意義。不過,如果我想檢視一些總和資料呢?“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)

Pandas透視表(pivot_table)詳解

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

1

2

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

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

Pandas透視表(pivot_table)詳解

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

1

2

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

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

Pandas透視表(pivot_table)詳解

此外,你也可以提供一系列的聚合函數,并将它們應用到“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

Pandas透視表(pivot_table)詳解

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

進階透視表過濾

一旦你生成了需要的資料,那麼資料将存在于資料幀中。是以,你可以使用自定義的标準資料幀函數來對其進行過濾。

如果你隻想檢視一個管理者(例如Debra Henley)的資料,可以這樣:

1 table.query('Manager == ["Debra Henley"]')
Pandas透視表(pivot_table)詳解

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

1 table.query('Status == ["pending","won"]')
Pandas透視表(pivot_table)詳解

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

The full notebook is available if you would like to save it as a reference.

如果你想将其儲存下來作為參考,那麼這裡提供完整的筆記。

備忘單

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

Pandas透視表(pivot_table)詳解