使用 Pandas DataFrame Styler 格式化日期时间索引

Formatting Datetime Index with Pandas DataFrame Styler

我正在使用 Pandas DataFrames 的 属性 样式来创建 HTML tables 用于电子邮件。

我遇到的问题是,当我希望它显示为日期时,我有一个显示为日期时间戳的日期时间索引。我对时间部分不感兴趣。在解释器中,DataFrame 确实打印正确(只显示日期部分)。但是,当我在使用 table 的样式 属性 进行样式化后进行渲染时,它会生成 HTML 并同时显示时间部分。我研究过使用 style.format() 但我无法访问索引列。 我会重置索引以使日期时间列成为普通列...但是我的 header 列是 MultIndex。如果我拉平并且不使用索引,table 看起来很奇怪。

不幸的是,我在 .style 文档中发现了这个:

Limitations

DataFrame only (use Series.to_frame().style) The index and columns must be unique No large repr, and performance isn’t great; this is intended for summary DataFrames You can only style the values, not the index or columns You can only apply styles, you can’t insert new HTML entities Some of these will be addressed in the future.

https://pandas.pydata.org/pandas-docs/stable/style.html#Limitations

我发帖是想看看是否有人对我如何解决这个问题有任何想法。谢谢!

显示问题的示例 table: example_table_link

生成代码table:

account_day_df = merged[['Day', 'Metric1', 'Metric2', 'Metric3', 'Metric4', 'Campaign type']]
account_day_df = account_day_df.groupby(['Day', 'Campaign type']).sum()
account_day_df.loc[:, 'Metric5'] = account_day_df['Metric1'] / account_day_df['Metric4']
account_day_df = account_day_df.unstack('Campaign type')

html += (
    account_day_df.style
        .background_gradient(cmap=cm, subset=['Metric5'])
        .set_table_attributes('border="1" class="dataframe table table-hover table-bordered"')
        .render(i)
)

您可以通过 df.index = df.index.strftime("%Y-%d-%m") 使用 strftime() 将索引转换为 object 而不是 datetime。这是一个例子:

data = np.random.randn(10, 5)
index = pd.date_range('20130101', periods=10, freq='D')
pd.DataFrame(data, index=index).style.format("{:.2}")

pd.DataFrame(data, index=index.strftime("%Y-%m-%d")).style.format("{:.2}")

作为 Styler enhancements in pandas 1.4.0 format_index 的一部分,现在可以直接用于索引的样式:

例如:

df.style.format_index(lambda s: s.strftime("%Y-%m-%d"))

当然,这可以与其他样式链接:

(
    df.style.format_index(lambda s: s.strftime("%Y-%m-%d"))
        .format(precision=2)
        .background_gradient()
)


设置:

import pandas as pd
from numpy.random import Generator, MT19937

rng = Generator(MT19937(10))
df = pd.DataFrame(
    rng.random(size=(10, 2)),
    index=pd.date_range('2022-01-01', periods=10, freq='D')
)

df.style