pandas
的DataFrame
可以通過設置參數使得在jupyter notebook
中顯示的更加美觀,
但是,將DataFrame
的數據導出excel
時,卻只能以默認最樸素的方式將數據寫入excel
。
本文介紹一種簡單易用,讓導出的excel
更加美觀的方法。
1. 概要
首先,引入一個庫StyleFrame
,這個庫封裝 pandas
和openpyxl
,讓我們輕鬆的設置DataFrame
的樣式並導出到excel
中。
安裝很簡單:
pip install styleframe
這個庫主要包含3個模塊:
styleframe
:相當於這個庫的主入口,它封裝了DataFrame
對象。styler
:用來單元格的樣式。utils
:常用樣式元素的輔助類,比如數字和日期格式、顏色和邊框類型等。
安裝成功之後,下面通過示例看看如何使用。
2. 準備數據
下面示例中使用的數據採集自鏈家網的真實成交數據。
數據下載地址:https://databook.top/。
導入數據:
import pandas as pd
fp = "D:/data/南京二手房交易/南京建鄴區.csv"
df = pd.read_csv(fp)
# 爲了簡化,只取10條數據來演示導出效果
df = df.head(10)
3. 行列設置
先看看默認導出excel
的效果。
output = "d:\data\output.xlsx"
df.to_excel(output, index=None)
默認導出的樣式就是這樣,所有單元格都一樣,不管單元格的內容是什麼。
3.1. 設置自適應
第一步,我們設置內容自適應(shrink_to_fit
),確保每個單元格中的內容能夠完整顯示。
from styleframe import StyleFrame, Styler, utils
style = Styler(shrink_to_fit=True)
sf = StyleFrame(df, styler_obj=style)
writer = sf.to_excel(output)
writer.close()
可以看出,StyleFrame
的默認導出樣式,給有數據的表格加了邊框。
使用shrink_to_fit=True
樣式之後,每個單元格的內容可以完整顯示了。
3.2. 設置列寬
從上面的效果,我們發現,所有列的寬度是一樣的,無論列中的內容有多長。
我們可以設置某些文字內容比較多列更寬一些。
sf.set_column_width_dict(
{
"name": 25,
"positionInfo": 20,
"advantage": 15,
"dealCycleDays": 16,
}
)
調整之後,內容看起來更清晰了。
3.3. 設置表頭,內容
接下來,我們通過字號,對齊方式,背景色以及是否加粗來區分表頭和內容部分。
header_style = Styler(
bg_color="yellow",
bold=True,
font_size=12,
horizontal_alignment=utils.horizontal_alignments.center,
vertical_alignment=utils.vertical_alignments.center,
)
content_style = Styler(
shrink_to_fit=True,
font_size=8,
horizontal_alignment=utils.horizontal_alignments.left,
)
sf.apply_column_style(sf.columns, content_style)
sf.apply_headers_style(header_style)
內容更加緊湊了,表頭部分也更突出了。
3.4. 設置行間隔顏色
最後,我們在優化下內容顯示部分,用不同的背景色區分奇數行和偶數行。
row_style = Styler(
bg_color="#32CD32",
shrink_to_fit=True,
font_size=8,
horizontal_alignment=utils.horizontal_alignments.left,
)
# 計算要設置背景色的行索引
indexes = list(range(1, len(sf), 2))
sf.apply_style_by_indexes(indexes, styler_obj=row_style)
4. 樣式設置
樣式設置主要是Styler
這個模塊提供的功能。
通過Styler
類提供的接口,我們可以設置靈活的控制導出的樣式。
4.1. 字體
我們給第一行設置不同的字體(font="STKaiti"
),看看導出的效果:
first_line_style = Styler(
shrink_to_fit=True,
font="STKaiti",
font_size=14,
horizontal_alignment=utils.horizontal_alignments.left,
)
sf.apply_style_by_indexes(indexes_to_style=[0], styler_obj=first_line_style)
第一行的字體是華文楷體,和其他行不一樣。
4.2. 顏色
再把第一行的字調成藍色(font_color="blue"
)。
first_line_style = Styler(
shrink_to_fit=True,
font="STKaiti",
font_size=14,
font_color="blue",
horizontal_alignment=utils.horizontal_alignments.left,
)
sf.apply_style_by_indexes(indexes_to_style=[0], styler_obj=first_line_style)
4.3. 背景色
再給第一行加一個紅色背景(bg_color="red"
)。
first_line_style = Styler(
shrink_to_fit=True,
font="STKaiti",
font_size=14,
font_color="blue",
bg_color="red",
horizontal_alignment=utils.horizontal_alignments.left,
)
sf.apply_style_by_indexes(indexes_to_style=[0], styler_obj=first_line_style)
4.4. 邊框
邊框是區隔,突出內容的一種手段,比如,我們可以在表頭部分用實線粗邊框(border_type=utils.borders.thick
),內容部分用虛線細邊框(border_type=utils.borders.dashed
)。
header_style = Styler(
bg_color="yellow",
bold=True,
font_size=14,
border_type=utils.borders.thick,
)
content_style = Styler(
shrink_to_fit=True,
font_size=12,
border_type=utils.borders.dashed,
)
sf.apply_column_style(sf.columns, content_style)
sf.apply_headers_style(header_style)
4.5. 數字和日期
最後,看看如何定製數字(number_format
)和日期(date_format
)的顯示方式。
我們把上面示例中的總價(totalPrice
)保留兩位小數,日期(DealDate
)改爲只顯示月和日。
num_style = Styler(
shrink_to_fit=True,
font_size=12,
number_format=utils.number_formats.general_float,
border_type=utils.borders.dashed,
horizontal_alignment=utils.horizontal_alignments.left,
)
sf.apply_column_style(["totalPrice", "unitPrice"], num_style)
date_style = Styler(
shrink_to_fit=True,
font_size=12,
date_format="DD/MM",
border_type=utils.borders.dashed,
horizontal_alignment=utils.horizontal_alignments.left,
)
sf.apply_column_style("dealDate", date_style)
5. 總結
導出分析結果是我們做數據分析的最後一步,也是最容易被忽視的一步。
我們常常把大部分的精力都會花在數據的整理和分析上,最後給客戶提供一個簡易的報告和數據。
殊不知,導出一個美觀清晰的分析結果和數據,反而更能得到客戶的肯定和信任,因爲這纔是客戶能夠切身感知到的部分,否則花在數據整理和分析的精力再多,也不能讓客戶有直接的感受。