如何在Pandas applymap中依据Policy列设置Snapshot Time单元格样式
问题说明
现有如下表格数据存储在Pandas DataFrame中:
| DB | Policy | Snapshot Time |
|---|---|---|
| A-DB | PROD_BACKUP | 10/17/2022 12:00:00 |
| B-DB | PROD_BACKUP | 10/16/2022 10:00:00 |
| C-DB | NONPROD_BACKUP | 10/15/2022 16:00:00 |
当前代码用applymap实现了Snapshot Time超过24小时就高亮单元格,但需求要改成:PROD_BACKUP策略对应24小时阈值,NONPROD_BACKUP策略对应72小时阈值,需要调整代码让高亮逻辑能获取当前行的Policy值来判断阈值。
解决方案
因为applymap是逐单元格处理,无法直接获取同一行的其他列数据,所以需要改用apply方法按行处理,这样就能拿到当前行的Policy值来选择对应阈值。具体修改如下:
1. 调整高亮函数
重写highlight_snap函数,让它接收整行数据,先根据Policy列的值确定阈值,再调用原有的highlight_cells函数生成样式:
def highlight_snap(row, check_time): # 根据当前行的Policy选择对应阈值 limit = 24 if row['Policy'] == 'PROD_BACKUP' else 72 return highlight_cells(row['Snapshot Time'], check_time, limit)
2. 替换applymap为按行处理的apply
把原来的applymap调用换成apply,指定axis=1(按行处理),同时确保只给Snapshot Time单元格应用样式:
df_styler = df_styler.apply( lambda row: ['', '', highlight_snap(row, report_start_time)], axis=1 )
这里lambda返回的列表和列数对应,前两列(DB、Policy)返回空样式,仅第三列(Snapshot Time)应用高亮逻辑。
完整修改后的代码
import pandas as pd from datetime import datetime,timedelta report_start_time = datetime.now() def highlight_cells(val, check_time, limit): time_diff = check_time - val total_hours = (time_diff.days*24) + (time_diff.seconds / (60*60)) if total_hours >= limit: format_code = '''background-color: #B00202; font-weight: bold''' else: format_code = '' return format_code def highlight_snap(row, check_time): # 根据Policy选择对应阈值 limit = 24 if row['Policy'] == 'PROD_BACKUP' else 72 return highlight_cells(row['Snapshot Time'], check_time, limit) d = {'DB': ['A-DB', 'B-DB', 'C-DB'], 'Policy': ['PROD_BACKUP','PROD_BACKUP','NONPROD_BACKUP'], 'Snapshot Time': ['10/17/2022 12:00:00','10/16/2022 10:00:00','10/15/2022 16:00:00']} df = pd.DataFrame(data=d) df['Snapshot Time'] = pd.to_datetime(df['Snapshot Time']) table_styler = [ { "selector" : "table", "props":[ ("border", "3px solid black"), ("border-collapse","separate"), ("width", "100%") ] }, { "selector" : "th", "props":[ ("color","black"), ("background-color", "#F5F3F3"), ("border", "1px solid gray"), ("padding", "3px 3px"), ("border-collapse","separate"), ("font-size", "16px") ] }, { "selector" : "td", "props":[ ("color","black"), ("border", "1px solid gray"), ("padding", "1px 3px"), ("font-size", "14px") ] } ] df_styler = df.style.set_table_styles(table_styler) # 替换applymap为按行处理的apply df_styler = df_styler.apply( lambda row: ['', '', highlight_snap(row, report_start_time)], axis=1 ) print(df_styler.to_html())
关键说明
apply(axis=1)让函数可以访问整行数据,从而动态获取Policy列的值来设置阈值。- 返回的样式列表和列数一一对应,确保只有
Snapshot Time列被应用高亮规则。
内容的提问来源于stack exchange,提问作者Nick S
相关产品推荐
相关产品推荐

