根据 2 种不同的条件更改 Pandas 行背景颜色和字体颜色

change Pandas Row background colour and Font Colors based on 2 different conditions

我有一个代码可以在 Rising 为 False 时更改单元格背景颜色。如果 Index 中的值为 Nifty 50.

,我想将 Cell 颜色更改为绿色

因此,如果任何行来自 Nifty 50Rising 为 False,则 Nifty 50 单元格应位于该唯一单元格的绿色背景中,所有其他单元格应为红色。

这就是我想要的 Dataframe 的样子:整行是红色的,如果 RisingFalse or 0Index 的颜色根据它是否来自 Nifty-50/100/200

而改变

而换色代码如下:

def highlight_falling(s, column:str):
        '''
        Highlight The rows where average is falling
        args:
            s: Series
            column: Column name(s)
        '''
        is_max = pd.Series(data=False, index=s.index)
        is_max[column] = s.loc[column] == True
        return ['' if is_max.any() else 'background-color: #f7a8a8' for v in is_max]

picked.style.apply(highlight_falling, column=['Rising'], axis=1) # picked is the DF

这里我想给 50,100,200,500 单元格的索引作为 [Green,Blue,Magenta. White](只是棕褐色的例子)

我们可以使用 Series.map 将列中的值与新的颜色样式相关联。然后,我们将在行样式之后应用 Index 列样式,以覆盖之前放置的红色:

def highlight_falling(f: pd.DataFrame, column: str):
    # Create an Empty DataFrame
    f_styles = pd.DataFrame('', index=f.index, columns=f.columns)
    # Apply Styles based on column. (Set red where not Truthy)
    f_styles.loc[~(f[column].astype(bool)), :] = 'background-color: #f7a8a8'
    return f_styles


def highlight_nifty(s: pd.Series):
    return 'background-color: ' + s.map({
        'Nifty 50': 'green',
        'Nifty 100': 'blue',
        'Nifty 200': '#888888'
    })  # Map to colour codes


# Save Styler To Re-use (can also Chain)
styler = picked.style
# Apply Row Colour (Do not pass column as List[str] use str!!)
styler.apply(highlight_falling, column='Rising', axis=None)
# Apply Index Column Colours
styler.apply(highlight_nifty, subset='Index')


映射字典也可以用 dictzip 创建,如果想指定颜色列表可以使用 unique to get all unique values from the Index column, then natsorted 可以用来对它们进行排序(安全的字母数字排序) :

from natsort import natsorted
from typing import List


def highlight_falling(f: pd.DataFrame, column: str):
    # Create an Empty DataFrame
    f_styles = pd.DataFrame('', index=f.index, columns=f.columns)
    # Apply Styles based on column. (Set red where not Truthy)
    f_styles.loc[~(f[column].astype(bool)), :] = 'background-color: #f7a8a8'
    return f_styles



def highlight_nifty(s: pd.Series, colours: List[str]):
    return 'background-color: ' + s.map(
        # Build Colour Map Dynamically based on unique values from column
        dict(zip(natsorted(s.unique()), colours))
    )  # Map to colour codes


# Save Styler To Re-use (can also Chain)
styler = picked.style
# Apply Row Colour (Do not pass column as List[str] use str!!)
styler.apply(highlight_falling, column='Rising', axis=None)
# Apply Index Column Colours
styler.apply(highlight_nifty, subset='Index',
             colours=['green', 'blue', '#888888'])