【问题标题】:How can I highlight categorical variables in pandas dataframe in Python?如何在 Python 中突出显示 pandas 数据框中的分类变量?
【发布时间】:2021-11-09 20:09:13
【问题描述】:

我有一个名为 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: the truth value of a Series is ambiguous。使用 a.empty、a.bool()、a.item()、a.any() 或 a.all()。在这里突出显示的合适方法是什么?

我能够仅使用突出显示具有空值的单元格

value_matrix_classification.style.highlight_null(null_color = "gray")

我在这里附上屏幕截图只是为了方便读者。

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

【问题讨论】:

    标签: python pandas dataframe background-color pandas-styles


    【解决方案1】:

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

    this Pandas documentation section

    编辑:您还希望 highlight_cells 仅返回 f"background-color: {color}",而不是包含在列表中。

    【讨论】:

      【解决方案2】:

      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 repr,而是映射字典中未出现的 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
      

      【讨论】:

        【解决方案3】:

        要添加更多细节,假设您有

        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
        

        为了了解发生了什么,我们将列与 value=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().
        

        上面的比较等于下面的情况,不清楚结果应该是什么。应该是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!")
          
        

        【讨论】:

          猜你喜欢
          • 2021-06-12
          • 2014-06-20
          • 1970-01-01
          • 2020-08-21
          • 1970-01-01
          • 1970-01-01
          • 2022-10-02
          • 1970-01-01
          • 2015-10-09
          相关资源
          最近更新 更多