使用 pandas 数据框样式器更正行着色

Correct row coloring with pandas dataframe styler

如果颜色基于前一行,我会花时间解决 table 行的着色问题。

在四点系统中有以下逻辑。如果 0 或 1 点,行颜色应为红色,如果 3 或 4 点,行颜色应为绿色,如果 2 点,则颜色应与之前的行相同。

我无法确定数据框中前一行的颜色。我用 'temp' 列解决了它。不幸的是,此列显示在 HTML table.

def should_colored(sum_of_points):
    if sum_of_points > 2:
        return True
    elif sum_of_points < 2:
        return False
    else:
        return np.NaN

def determine_coloring_for_row(results):
    tmp = pd.DataFrame(results.values, columns=['color_result'])

    tmp['color_result'] = tmp['color_result'].apply(lambda i : should_colored(i))    
    tmp['color_result'].fillna(method='ffill', inplace=True)

    return tmp['color_result'].values

def color_row(row, number_of_columns):
    color = 'green' if row['color_result'] else 'red' 

    return ['background-color: %s' % color] * number_of_columns

df['color_result'] = determine_coloring_for_row(df['sum_of_points'])
df.style.apply(color_row, number_of_columns = len(df.columns), axis=1)

有人知道如何使用 style.apply 或隐藏元数据列来解决这个问题吗?

我认为新列不是必需的,只需要 DataFrame of styles 原始 DataFrame 列和索引,并按条件设置行 mask:

def highlight(x):
    c1 = 'background-color: green'
    c2 = 'background-color: red' 

    df1 = pd.DataFrame(c2, index=x.index, columns=x.columns)
    df1 = df1.mask(df['sum_of_points'].map(should_colored).ffill(), c1)
    #print (df1)
    return df1

df.style.apply(highlight, axis=None)

样本:

df = pd.DataFrame({'sum_of_points':[0,1,2,1,2,3,4,1,2,2,4,5,0,1,2],
                   'A':range(15)})

print (df)
     A  sum_of_points
0    0              0
1    1              1
2    2              2
3    3              1
4    4              2
5    5              3
6    6              4
7    7              1
8    8              2
9    9              2
10  10              4
11  11              5
12  12              0
13  13              1
14  14              2

def should_colored(sum_of_points):
    if sum_of_points > 2:
        return True
    elif sum_of_points < 2:
        return False
    else:
        return np.NaN

def highlight(x):
    c1 = 'background-color: green'
    c2 = 'background-color: red' 

    df1 = pd.DataFrame(c2, index=x.index, columns=x.columns)
    df1 = df1.mask(x['sum_of_points'].map(should_colored).ffill(), c1)
    return df1

df.style.apply(highlight, axis=None)