【呆鳥譯Py】淺談 Pandas 樣式

淺談Pandas樣式

Python大咖談 - Kenneth Reitz 與 Mike Driscoll
Python大咖談 - Brett Cannon(一)
Python大咖談 - Brett Cannon(二)

簡介

大家都知道 Excel 可以設(shè)定單元格格式,還支持單元格迷你圖,其實(shí) Pandas 也可以,本文參照 Chris MoffittStylin’ with Pandas 一文,為大家簡單介紹一下 Pandas 如何實(shí)現(xiàn) DataFrame 的樣式設(shè)置,主要內(nèi)容如下:

  1. 設(shè)置 DataFrame 不同列的樣式,如千分號(hào)、小數(shù)位數(shù)、貨幣符號(hào)、日期格式,百分比等;

  2. 突出顯示 DataFrame 中某一列里符合某些條件的數(shù)據(jù),如,按不同顏色顯示某列中的最大值與最小值;

  3. 以不同漸變色展示每一行數(shù)據(jù)占總數(shù)據(jù)的比例大小,占比越大,顏色越深,占比越小,則顏色越淺;

  4. 實(shí)現(xiàn)類似 Excel 迷你條形圖的功能,根據(jù)數(shù)據(jù)大小,在單元格里顯示迷你條形圖;

  5. 利用 Sparklines 支持庫,配合 Pandas 繪制迷你走勢圖。需要先用 pip install sparklines 命令安裝 Sparklines 支持庫。

什么是樣式?為什么與使用樣式?

樣式的基本理念是用戶在調(diào)整數(shù)據(jù)顯示形式的同時(shí),不會(huì)影響數(shù)據(jù)本身的計(jì)算操作。

最直觀的樣式是貨幣符號(hào),如果只顯示一個(gè)數(shù)字,比如 25.06,讀者并不清楚這個(gè)數(shù)字代表的到底是美元、英鎊、日元還是人民幣,但 ¥25.06,大家就都知道這是人民幣了,由此可見,樣式可以讓數(shù)據(jù)提供更多信息。

百分比也是數(shù)據(jù)樣式的重要形式,0.12 就不如 12% 更直觀,用百分比說明數(shù)據(jù)更清晰,也更簡單。

Pandas 支持不同樣式,可以用更易理解的方式顯示數(shù)據(jù),但并未修改數(shù)據(jù)的類型,所以依然還可以用 Pandas 提供的各種數(shù)學(xué)、日期、字符串函數(shù)處理數(shù)據(jù)。

Pandas 樣式還包括內(nèi)容里提及的高級(jí)樣式,比如添加顏色與條形圖等可視化元素。本文只是簡要介紹 Pandas 樣式的基本功能,方便大家快速上手,提高數(shù)據(jù)分析報(bào)表的可讀性。

數(shù)據(jù)文件說明

  1. 數(shù)據(jù)文件為 2018年銷售匯總表.csv點(diǎn)擊下載),本文件引用的是原文作者 Chris 虛構(gòu)的一家企業(yè) 2018 年的銷售數(shù)據(jù),但漢化了數(shù)據(jù)表的標(biāo)題,方便大家在代碼中識(shí)別數(shù)據(jù)列的信息;

  2. 文件格式從原文的 xlsx 改為 csv

  3. 文件共有 5 列,分別為賬號(hào)(字符串)、姓名(字符串)、單品(字符串)、數(shù)量(整數(shù))、單價(jià)(2 位小數(shù))、金額(2 位小數(shù))、日期(DateTime)

Jupyter Notebook 示例文件,點(diǎn)擊下載

0.1 導(dǎo)入 Numpy 與 Pandas

import numpy as np
import pandas as pd

下面的代碼與原文不同,原文用的是 xlsx 文件,本文用的是 csv 文件,需要解析日期。

另外需要注意,數(shù)據(jù)文件與 ipynb 文件要在同一文件夾下。

df = pd.read_csv('2018年銷售匯總表.csv',parse_dates=['日期'])

0.2 df.head() 預(yù)覽數(shù)據(jù)

df.head()

0.3 匯總數(shù)據(jù),根據(jù)客人姓名分組計(jì)算 2018 年每個(gè)客人的平均金額與消費(fèi)總額

df.groupby('姓名')['金額'].agg(['mean','sum'])
匯總統(tǒng)計(jì)消費(fèi)金額

1.1 設(shè)置金額樣式:貨幣符號(hào)、千分號(hào)、2 位小數(shù)

可以看到平均值顯示的是 6 位小數(shù),沒有貨幣符號(hào),整數(shù)部分也沒有千分號(hào)。此時(shí),可以用 DataFrame 的 style.format 修飾。

代碼如下,匯總計(jì)算的代碼與上面相同,但多了 .style.format('${0:,.2f}'),引號(hào)里的 $ 符號(hào)代表美元,冒號(hào)(:)后的逗號(hào)代表千分號(hào),.2f 代表 2 位小數(shù)。

(
    df.groupby('姓名')['金額']
    .agg(['mean', 'sum'])
    .style.format('${0:,.2f}')
)

調(diào)整以后,數(shù)據(jù)顯示如下:

貨幣樣式示例1

可以看到,用了 .style.format() 函數(shù)以后,DataFrame 中平均值(mean)列顯示的數(shù)據(jù)變成了帶美元符號(hào)標(biāo)記、整數(shù)部分帶千分號(hào)、小數(shù)僅保留兩位的樣式,這種樣式更便于理解金額這一概念。

如果只想保留整數(shù),可使用 .style.format('${0:,.0f}'),把上面代碼里的 2 改為 0,即可。

(
    df.groupby('姓名')['金額']
    .agg(['mean', 'sum'])
    .style.format('${0:,.0f}')
)
貨幣樣式示例2

此時(shí),可以看到,貨幣數(shù)據(jù)已經(jīng)按四舍五入的原則保留了整數(shù)。

如需了解更多 Python 字符串格式化示例,請參照 Python String Format Cookbook

1.2 設(shè)定日期與百分比樣式

接下來用 groupby 函數(shù),按銷售日期計(jì)算每月銷售金額及其占年度銷售總額的比例。

monthly_sales = df.groupby([pd.Grouper(key='日期', freq='M')])['金額'].agg(['sum']).reset_index()
monthly_sales['月占比'] = monthly_sales['sum']/df['金額'].sum()
日期與百分比示例1

此處可以看到,日期顯示的是每個(gè)月的最后一天,比例一列則顯示為 6 位小數(shù),這種樣式顯然非常不直觀,但一列一列調(diào)整樣式也不是好方法,能不能一次性調(diào)整多列數(shù)據(jù)的樣式呢?答案自然是,能!用樣式字典就可以了。

format_dict = {'sum': '${0:,.0f}', '日期': '{:%Y-%m}', '月占比': '{:.2%}'}
monthly_sales.style.format(format_dict).hide_index()

上面的代碼,首先把 format_dict 定義為一個(gè)樣式字典,分別設(shè)置了匯總金額(sum)日期月占比三列的樣式。其中,匯總金額為帶美元符號(hào)、千分號(hào)、0 位小數(shù)的數(shù)字;日期為經(jīng)典的“年月”格式,月占比則為帶 2 位小數(shù)的百分比形式。

第二行代碼,使用 style.format() 調(diào)用了第一行代碼設(shè)定的樣式字典(format_dict ),并用 hide_index() 隱藏了索引,隱藏索引的功能在很多情況下都有用,大家可以試試。

日期與百分比示例2

這樣一來,DataFrame 的數(shù)據(jù)顯示就變得比較可耐了,是不是數(shù)據(jù)顯示得更清晰了,而且實(shí)現(xiàn)起來其實(shí)也很簡單。

2. 突出顯示最大值與最小值

Pandas 還支持用顏色突出顯示符合條件的數(shù)據(jù),類似 Excel 里的條件格式,本文主要演示一下如何突出顯示某列數(shù)據(jù)里的最大值(淺綠色)與最小值(紅色)。

(
    monthly_sales
    .style
    .format(format_dict)
    .hide_index()
    .highlight_max(color='lightgreen')
    .highlight_min(color='red')
)
突出顯示最大值與最小值

這里的 color 參數(shù)除了可以用lightgreen 這樣的關(guān)鍵詞以外,還可以使用 '#cd4f39' 這樣的顏色代碼,更靈活。而且可以設(shè)置多個(gè)條件,比如可以同時(shí)設(shè)置 highlight_maxhighlight_min

3. 漸變色樣式

只改變數(shù)字的樣式,還不夠,我們還想要更多,還想用顏色的深淺漸變來表示某一列數(shù)據(jù)占比的多少,其實(shí)這也是 Excel 已經(jīng)提供了的功能,Pandas 也支持了。實(shí)現(xiàn)這一目標(biāo),需要使用 stylebackground_gradient 函數(shù)。

(
    monthly_sales.style
    .format(format_dict)
    .background_gradient(subset=['sum'], cmap='BuGn')
)

上述代碼設(shè)定了顏色漸變針對(duì)的列,subset=['sum'],色圖用的是 cmap 參數(shù),值為'BuGn',是一種綠色的漸變色圖,色圖的值請參閱 matplotlib 的文檔 ,還有更多色彩可選。

顯示效果如下,是不是覺得更直觀了?

漸變色樣式

4. 迷你條形圖樣式

除了漸變色,Pandas 還支持在 DataFrame 單元格里顯示迷你條形圖。

(
    monthly_sales
    .style
    .format(format_dict)
    .hide_index()
    .bar(color='#FFA07A', vmin=100_000, subset=['sum'], align='zero')
    .bar(color='lightblue', vmin=0, subset=['月占比'], align='zero')
    .set_caption('2018年銷售一覽表')
)

這里使用的是 stylebar 函數(shù),分別需要設(shè)置幾個(gè)參數(shù),color 還是支持顏色編碼與關(guān)鍵詞,vmin 是基準(zhǔn)值,比如銷售額的基準(zhǔn)值是 10 萬,百分比的基準(zhǔn)值是 1,subset 是針對(duì)的列,align 則代表對(duì)齊方式。

此外,還可以用 set_caption 函數(shù)設(shè)置 DataFrame 的標(biāo)題。代碼執(zhí)行后,顯示效果如下。

迷你條形圖樣式

5. Sparklines - 走勢圖

走勢圖這種樣式不是 Pandas 的內(nèi)置樣式,但依然很實(shí)用,也很酷,它是一個(gè)叫 sparklines 的支持庫提供的。詳情請參閱它的文檔 ,這個(gè)模塊可以為 Pandas 的 DataFrame 添加迷你走勢圖。

首先,導(dǎo)入 sparklines

import sparklines

接著,定義調(diào)用 sparklines 的函數(shù);

def sparkline_str(x):
    bins=np.histogram(x)[0]
    sl = ' '.join(sparklines(bins))
    return sl

sparkline_str.__name__ = "走勢圖"

最后,在 groupby 函數(shù)里調(diào)用定義的 sparkline_str 函數(shù);

df.groupby('姓名')['數(shù)量', '金額'].agg(['mean', sparkline_str])
迷你走勢圖示例

這種匯總功能可以很直觀的顯示數(shù)據(jù),更有趣的是這個(gè)走勢圖是由純文本組成的,又簡單,又實(shí)用,對(duì)不?

總結(jié)

Pandas 的樣式功能備受歡迎,尤其是分析師完成數(shù)據(jù)分析工作后,要給別人展示數(shù)據(jù)分析結(jié)果的時(shí)候,這個(gè)功能可以讓你的數(shù)據(jù)分析報(bào)告更直觀,更清晰。除了本文介紹的功能之外,其實(shí)還有更多樣式與函數(shù)功能供你選擇,本文只是引導(dǎo)您上手 Pandas 樣式的基礎(chǔ)入門,想要玩的更花俏,請自行研究 Pandas 官方的樣式文檔

最后,感謝 Alexas_Fotos 提供的圖片,非常有創(chuàng)意。

Python大咖談 - Kenneth Reitz 與 Mike Driscoll
Python大咖談 - Brett Cannon(一)
Python大咖談 - Brett Cannon(二)

【呆鳥云】翻譯不易,四處求證、三天翻譯、兩天校對(duì),只求一秒點(diǎn)贊 _

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容