如何在 Python 中突出显示 pandas 数据框中的分类变量?

How can I highlight categorical variables in pandas dataframe in Python?

我有一个名为 value_matrix_classification 的 pandas 数据框,如下所示:

{('wind_on_share',
  'Wind-onshore power generation'): {('AIM/CGE 2.0',
   'ADVANCE_2020_WB2C'): 'high', ('AIM/CGE 2.0',
   'ADVANCE_2030_Price1.5C'): 'high', ('AIM/CGE 2.0',
   'ADVANCE_2030_WB2C'): 'high', ('IMAGE 3.0.1',
   'ADVANCE_2020_WB2C'): 'low', ('IMAGE 3.0.1',
   'ADVANCE_2030_WB2C'): 'low', ('MESSAGE-GLOBIOM 1.0',
   'ADVANCE_2020_WB2C'): 'low'},
 ('wind_off_share',
  'Wind-offshore power generation'): {('AIM/CGE 2.0',
   'ADVANCE_2020_WB2C'): nan, ('AIM/CGE 2.0',
   'ADVANCE_2030_Price1.5C'): nan, ('AIM/CGE 2.0',
   'ADVANCE_2030_WB2C'): nan, ('IMAGE 3.0.1',
   'ADVANCE_2020_WB2C'): 'low', ('IMAGE 3.0.1',
   'ADVANCE_2030_WB2C'): 'low', ('MESSAGE-GLOBIOM 1.0',
   'ADVANCE_2020_WB2C'): 'low'}}

右边的两列包含low, medium and high,它们是分类变量。我使用 pd.cut(value_matrix_classification, bins = 3, labels = ["low", "medium", "high"]

创建了它们

我想突出显示 pandas 数据框,这样高、中、低和 NaN 值分别有红色、橙色、黄色和背景色。

我写了下面的函数

def highlight_cells(x):
    if x == "high":
        color = "red"
    elif x=="medium":
        color = "orange"
    elif x=="low":
        color = "yellow"
    else:
        color = "gray"
    
    return [f"background-color: {color}"]

并将其应用于数据框

value_matrix_classification.style.apply(highlight_cells)

但是,这给出了 ValueError:Series 的真值不明确。使用 a.empty、a.bool()、a.item()、a.any() 或 a.all()。在这里突出显示的合适方法是什么?

我只能使用

突出显示具有空值的单元格
value_matrix_classification.style.highlight_null(null_color = "gray")

为了reader方便,我在这里附上截图。

如何根据给定类别(低、中和高)突出显示所有单元格?

apply 将整行或整列作为输入。请改用 applymap

this Pandas documentation section

编辑:您还需要 highlight_cells 到 return 只是 f"background-color: {color}",而不是包含在列表中。

要添加更多详细信息,假设您有

np.random.seed(0)
df = pd.DataFrame(np.random.randn(4,2), columns=list('AB'))

>>> df

   A         B
0 -0.686760 -0.791461
1 -0.497699 -1.287310
2  0.793787  0.525824
3  0.501172  1.695914

为了了解发生了什么,我们将列与值 =0.2 进行比较。返回一列布尔值。 and, or, not, if, while 也是如此。当您有多个条件时,您将返回多个列。

>>> df.B > 0.2

0     True
1     True
2    False
3    False
Name: B, dtype: bool

现在让我们进行比较

 if df.B > 0.2:
   print("do something")

 >>> ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

上面的比较等于下面的情况,不清楚结果应该是什么 be.Should 因为它不是零长度所以它是 True? False 因为有 False 值?目前还不清楚,所以 pandas 引发了一个 ValueError:

if Series([True, True, False, False]) > 0.2:
     print("do something")

所以我们需要将这些多个值转化为一个布尔值,这取决于我们想要做什么。

if pd.Series([True, True, False, False]).any(): # evaluates to True
   print("I checked if there was any True value in the Series!)

>>> I checked if there was any True value in the Series!

if pd.Series([True, True, False, False]).all(): # Evaluates to False
   print("I checked if there were all True values in the Series!")
  

Series.map + fillna 为每一列创建一系列样式是解决此类问题的更常见方法:

def highlight_cells(x):
    return 'background-color: ' + x.map(
        # Associate Values to a given colour code
        {'high': 'red', 'medium': 'orange', 'low': 'yellow'}
    ).fillna('gray')  # Fill unmapped values with default


value_matrix_classification.style.apply(highlight_cells)


每一列都映射到一组新的颜色代码。

这是仅使用第二列作为参考来确定样式的方式,但是 Styler.apply 将调用子集中的所有列:

value_matrix_classification.iloc[:, 1].map(
    {'high': 'red', 'medium': 'orange', 'low': 'yellow'}
)

AIM/CGE 2.0          ADVANCE_2020_WB2C            NaN
                     ADVANCE_2030_Price1.5C       NaN
                     ADVANCE_2030_WB2C            NaN
IMAGE 3.0.1          ADVANCE_2020_WB2C         yellow
                     ADVANCE_2030_WB2C         yellow
MESSAGE-GLOBIOM 1.0  ADVANCE_2020_WB2C         yellow
Name: (wind_off_share, Wind-offshore power generation), dtype: object

然后 fillna 用于将未映射的值替换为默认值。请注意,这不是 NaN 表示,而是 any 值的默认值,它没有出现在映射字典中:

value_matrix_classification.iloc[:, 1].map(
    {'high': 'red', 'medium': 'orange', 'low': 'yellow'}
).fillna('gray')

AIM/CGE 2.0          ADVANCE_2020_WB2C           gray  # NaN replaced with gray
                     ADVANCE_2030_Price1.5C      gray
                     ADVANCE_2030_WB2C           gray
IMAGE 3.0.1          ADVANCE_2020_WB2C         yellow
                     ADVANCE_2030_WB2C         yellow
MESSAGE-GLOBIOM 1.0  ADVANCE_2020_WB2C         yellow
Name: (wind_off_share, Wind-offshore power generation), dtype: object

最后,添加 css 属性:

'background-color: ' + value_matrix_classification.iloc[:, 1].map(
    {'high': 'red', 'medium': 'orange', 'low': 'yellow'}
).fillna('gray')
AIM/CGE 2.0          ADVANCE_2020_WB2C           background-color: gray  # valid css style
                     ADVANCE_2030_Price1.5C      background-color: gray
                     ADVANCE_2030_WB2C           background-color: gray
IMAGE 3.0.1          ADVANCE_2020_WB2C         background-color: yellow
                     ADVANCE_2030_WB2C         background-color: yellow
MESSAGE-GLOBIOM 1.0  ADVANCE_2020_WB2C         background-color: yellow
Name: (wind_off_share, Wind-offshore power generation), dtype: object