今天我們將以df
DataFrame來說明一些還沒有提過的gt
用法:
from datetime import date
import polars as pl
from great_tables import GT, from_column, google_font, loc, style, vals
df = pl.DataFrame(
{
"number": [0, 1, 2],
"lang": ["python", "ruby", None],
"color": ["red", "green", "blue"],
}
)
shape: (3, 3)
┌────────┬────────┬───────┐
│ number ┆ lang ┆ color │
│ --- ┆ --- ┆ --- │
│ i64 ┆ str ┆ str │
╞════════╪════════╪═══════╡
│ 0 ┆ python ┆ red │
│ 1 ┆ ruby ┆ green │
│ 2 ┆ null ┆ blue │
└────────┴────────┴───────┘
關於Polars如何處理缺失值,建議您可以參考其文件。
我們先來觀察一下,預設表格的渲染結果:
(
GT(df)
.tab_style(
style=[style.borders(color="red", weight="3px")],
locations=loc.body(columns="lang", rows=2),
)
.tab_style(
style=[style.borders(color="purple", weight="3px")],
locations=loc.body(columns="number", rows=0),
)
)
這裡我們額外使用style.borders()
標出兩個需要注意的格子:
None
(以紅色框標示)。GT.sub_missing()
GT.sub_missing(self, columns=None, rows=None, missing_text=None)
GT.sub_missing()可以讓我們取代欄位中的缺失值。例如:
(
GT(df)
.sub_missing()
.tab_style(
style=[style.borders(color="red", weight="3px")],
locations=loc.body(columns="lang", rows=2),
)
)
預設的缺失填補值為HTML格式的—
,也就是「"—"」。
我們可以使用missing_text
參數來指定想填補的缺失值。例如:
(
GT(df)
.sub_missing(columns=["lang"], missing_text="😮")
.tab_style(
style=[style.borders(color="red", weight="3px")],
locations=loc.body(columns="lang", rows=2),
)
)
這裡我們使用「"😮"」來填補缺失值。
GT.sub_zero()
GT.sub_zero(self, columns=None, rows=None, zero_text='nil')
GT.sub_zero()可以讓我們取代欄位中的零值。例如:
(
GT(df)
.sub_zero()
.tab_style(
style=[style.borders(color="purple", weight="3px")],
locations=loc.body(columns="number", rows=0),
)
)
預設的取代值為「"nil"」。
我們可以使用zero_text
參數來指定想要的取代值。例如:
(
GT(df)
.sub_zero(columns=["number"], zero_text="ZERO")
.tab_style(
style=[
style.borders(color="purple", weight="3px"),
style.text(font=google_font("Merriweather")),
],
locations=loc.body(columns="number", rows=0),
)
)
這裡我們使用「"ZERO"」來作為取代值。
不知道眼尖的您有沒有發現,「"ZERO"」的字型好像跟其它欄位不太一樣。
因為此處使用了google_font()來指定其為「"Merriweather"」字型,是0.12.0
版本的新功能。
from_column()
from_column(column, na_value=None, fn=None)
from_column()讓我們可以使用某一個欄位來指定顏色。例如:
(
GT(df).tab_style(
style=style.text(color=from_column("color")),
locations=loc.body(columns=["number"]),
)
)
這裡我們指定「"number"」欄內的字型顏色為「"color"」欄中標示的顏色。
下面這個例子則是指定「"number"」欄內的背景顏色為「"color"」欄中標示的顏色:
(
GT(df).tab_style(
style=style.fill(color=pl.col("color")),
locations=loc.body(columns=["number"]),
)
)
可是這裡面沒有from_column()
呀?
沒錯,這是gt
的一個特別功能,當傳入GT
的DataFrame為Polars型態時,可以使用類似pl.col("color")
的Polars expression來取代from_column()
。
vals
vals
是gt
一個比較少人知道的功能。相比於GT.fmt_*()
函數是針對一整欄進行格式化,vals
是針對一個或數個目標進行格式化。
我們以下舉vals.fmt_number()
、vals.fmt_date()
及vals.fmt_image()
三個例子說明。
vals.fmt_number()
vals.fmt_number(x, decimals=2, n_sigfig=None, drop_trailing_zeros=False, drop_trailing_dec_mark=True, use_seps=True, scale_by=1, compact=False, pattern='{x}', sep_mark=',', dec_mark='.', force_sign=False, locale=None)
vals.fmt_number()可以讓我們格式化一個或多個數值為整數。例如:
numbers = [100.1, 200.02, 300.033]
vals.fmt_number(numbers)
['100.10', '200.02', '300.03']
vals.fmt_date()
vals.fmt_date(x, date_style='iso', pattern='{x}', locale=None)
vals.fmt_date()可以讓我們將輸入格式化為日期。例如:
dates = [date(2024, 9, 1), date(2024, 10, 11)]
vals.fmt_date(dates, date_style="wd_m_day_year")
['Sun, Sep 1, 2024', 'Fri, Oct 11, 2024']
在沒有vals.fmt_date()
的幫忙下,想得到類似的輸出,可以這麼做:
[d.strftime("%a, %b %d, %Y") for d in dates]
# or
[f"{d:%a, %b %d, %Y}" for d in dates]
['Sun, Sep 01, 2024', 'Fri, Oct 11, 2024']
這邊需留意vals.fmt_date()
的日期是沒有前置的0,這是開發團隊所選擇的。
由於gt
內部使用Babel來解析日期,所以理論上是可以添加任何想要的格式。如果您有想要使用其它目前不支援的格式,請回報至GitHub讓我們知道。
vals.fmt_image()
vals.fmt_image()
須待PR#451合併之後才能使用。
vals.fmt_image()
可以讓我們利用類似GT.fmt_image()
的方式來得到一或多個經過格式化的圖片。接著我們將此輸出以html()
包裹後,即可於表格中任意component中顯示圖片。例如:
import polars as pl
from polars import selectors as cs
from great_tables import GT, vals, html
from importlib_resources import files
img_paths = files("great_tables") / "data/metro_images"
df = pl.DataFrame(
{
"col1": list("123"),
"col2": list("123"),
"col3": list("123"),
"group": ["grp_a", "grp_a", "grp_b"],
"row": ["row_1", "row_2", "row_3"],
}
)
img1, img2, img3, img4, img5, img6 = vals.fmt_image(
list("123456"), path=img_paths, file_pattern="metro_{}.svg"
)
(
GT(df)
.cols_label(**{"col1": html(img1), "col2": html(img2), "col3": html(img3)})
.tab_stub(groupname_col="group", rowname_col="row")
.tab_stubhead(html(img4))
.tab_header(title=html(img5))
.tab_source_note(html(img6))
.fmt_image(cs.starts_with("col"), path=img_paths, file_pattern="metro_{}.svg")
)
我們使用vals.fmt_image()
一次格式化六張位於gt
repo中的圖片。接下來將其各自包裹上html()
後,將圖片顯示於不同的component中。