如何基于两日对比为唯一ID应用Pandas单元格样式?
解决方法
你的代码主要存在三个问题:未将日期转为可排序的datetime类型、未按ID分组隔离对比、样式函数逻辑未针对组内数据设计。以下是修正后的完整实现:
步骤1:预处理数据(转换日期+排序)
先把日期转为datetime格式,确保能正确区分新旧日期,再按ID分组并按日期降序排列,让每组的最新数据排在最前面:
import pandas as pd data = { 'ID': ['B-1', 'B-1', 'F-1', 'F-1'], 'Analysis Date': ['31/05/2023', '21/05/2023', '31/05/2023', '21/05/2023'], 'Col 1': [10.91, 10.89, 7.24, 7.27], 'Col 2': [1, 2, 0.76, 0.80] } df = pd.DataFrame(data) # 转换日期格式为可排序的datetime类型 df['Analysis Date'] = pd.to_datetime(df['Analysis Date'], format='%d/%m/%Y') # 按ID分组,每组内按日期降序排列(最新日期数据在前) df = df.sort_values(['ID', 'Analysis Date'], ascending=[True, False])
步骤2:编写样式函数(按ID组对比)
编写针对每组数据的样式逻辑,只给最新日期的行设置颜色:
def highlight_change(df): # 创建与原DataFrame结构一致的空样式矩阵 styles = pd.DataFrame('', index=df.index, columns=df.columns) # 按ID分组处理每个产品的数据 for _, group in df.groupby('ID'): # 仅当组内至少有2条日期数据时才对比 if len(group) >= 2: latest_row = group.iloc[0] # 最新日期的行 old_row = group.iloc[1] # 上一个旧日期的行 # 遍历数值列,对比最新值与旧值 for col in ['Col 1', 'Col 2']: if latest_row[col] > old_row[col]: # 最新值上升,标红 styles.loc[latest_row.name, col] = 'background-color: red' elif latest_row[col] < old_row[col]: # 最新值下降,标绿 styles.loc[latest_row.name, col] = 'background-color: green' return styles # 应用样式(axis=None表示将整个DataFrame传入函数处理) styled_df = df.style.apply(highlight_change, axis=None) styled_df
关键说明
- 日期转换是核心:只有转为datetime类型,才能正确排序区分新旧日期
- 分组隔离对比:确保每个ID的只和自己的历史数据对比,不会跨产品混淆
- 样式矩阵精准控制:只给最新日期的行设置颜色,旧数据保持原样(若需要给旧数据加样式,可扩展逻辑)
内容的提问来源于stack exchange,提问作者ayz123
相关产品推荐
相关产品推荐

