根据数据框中单元格中的值将颜色应用于单元格

Posted

技术标签:

【中文标题】根据数据框中单元格中的值将颜色应用于单元格【英文标题】:apply color to the cells based on the value in cell in dataframe 【发布时间】:2021-03-28 04:38:23 【问题描述】:

工作代码

 import pandas as pd
import seaborn as sns
import matplotlib as mpl
import numpy as np
from matplotlib import colors,cm
from matplotlib import pyplot as plt

filename = r'c:\Users\91956\Desktop\time_50.csv'
df = pd.read_csv(filename,index_col=0)
select_col = df.columns[1:]

cmap = mpl.colors.LinearSegmentedColormap.from_list("", ["red","white", "green"])

def background_gradient(s, cmap='PuBu', low=0, high=0):
    s = pd.to_numeric(s, errors='coerce') #<-- here, string will become nan.
    m = s.min() #<---------- here
    M = s.max() #<-----------here
    rng = M - m
    norm = colors.TwoSlopeNorm(vmin=m - (rng * low), vcenter=0., vmax=M + (rng * high))
    normed = norm(s.values)
    c = [colors.rgb2hex(x) for x in plt.cm.get_cmap(cmap)(normed)]
    return ['background-color: %s' % color for color in c]

S = df.style.apply( background_gradient,
                    cmap=cmap,
                    low=0.5,
                    high=0.5,
                    subset= pd.IndexSlice[:, select_col],
                    axis=1
                )

html = S.render()
with open("output.html","w") as fp:
    fp.write(html)

我遇到了这个错误

文件“c:\Users\91956\Desktop\asdf.py”,第 29 行,在 m=df.min().min(), 文件“C:\Users\91956\AppData\Local\Programs\Python\Python39\lib\site-packages\pandas\core\generic.py”,第 11468 行,在 stat_func 返回 self._reduce( 文件“C:\Users\91956\AppData\Local\Programs\Python\Python39\lib\site-packages\pandas\core\series.py”,第 4248 行,在 _reduce 返回操作(代表,skipna=skipna,**kwds) 文件“C:\Users\91956\AppData\Local\Programs\Python\Python39\lib\site-packages\pandas\core\nanops.py”,第 129 行,在 f 结果= alt(值,轴=轴,skipna=skipna,**kwds) 文件“C:\Users\91956\AppData\Local\Programs\Python\Python39\lib\site-packages\pandas\core\nanops.py”,第 873 行,减少 结果 = getattr(值,方法)(轴) 文件“C:\Users\91956\AppData\Local\Programs\Python\Python39\lib\site-packages\numpy\core_methods.py”,第 43 行,在 _amin return umr_minimum(a, axis, None, out, keepdims, initial, where) TypeError:“numpy.ndarray”和“str”的实例之间不支持“>=”

更新 2 做了必要的改变。能够获得所需的输出。

【问题讨论】:

问题在于您的值范围的中位数不为零。调用background_gradientinfo时尝试设置low, high 什么应该是高和低以使零成为中位数,例如低 = -5 和高 = 5 之类的值? 它不起作用。 我已经更新了我的答案@AniketPatil:检查一下 它正在工作。 【参考方案1】:

这个answer 会有所帮助,还有这个answer。

创建示例df:

import pandas as pd
import numpy as np

np.random.seed(24)
df = pd.DataFrame('A': np.linspace(1, 10, 10))
df = pd.concat([df, pd.DataFrame(np.random.randn(10, 4), columns=list('BCDE'))],
               axis=1)
df.iloc[3, 3] = np.nan
df.iloc[0, 2] = np.nan

from matplotlib import colors

cmap=LinearSegmentedColormap.from_list('rg',["r","w","g"], N=256) 

def background_gradient(s, m, M, cmap='PuBu', low=0, high=0):
    s = pd.to_numeric(s, errors='coerce') #<-- here, string will become nan.
    print(s)
    rng = M - m
    norm = colors.DivergingNorm(vmin=m - (rng * low), vcenter=0., vmax=M + (rng * high))
    normed = norm(s.values)
    c = [colors.rgb2hex(x) for x in plt.cm.get_cmap(cmap)(normed)]
    return ['background-color: %s' % color for color in c]

x = df.apply(pd.to_numeric, errors='coerce') #<--- here string will be converted to `NaN` so that I can find out the max and min value.
df.style.apply(background_gradient,
               cmap=cmap,
               m=x.min().min(),
               M=x.max().max(),
               low=0.5,
               high=0.5, subset=pd.IndexSlice[:, ['B', 'C']]
              )

编辑:

通过subset=pd.IndexSlice[:, ['B', 'C']] 应用B 和C 列上应用颜色。

df.style.apply(background_gradient,
               cmap=cmap,
               m=df.min().min(),
               M=df.max().max(),
               low=0.5,
               high=0.5, subset=pd.IndexSlice[:, ['B', 'C']]
              )

编辑2:

from matplotlib import colors

cmap=LinearSegmentedColormap.from_list('rg',["r","w","g"], N=256) 

def background_gradient(s, cmap='PuBu', low=0, high=0):
    s = pd.to_numeric(s, errors='coerce')
    m = s.min() #<---------- here
    M = s.max() #<-----------here
    rng = M - m
    norm = colors.DivergingNorm(vmin=m - (rng * low), vcenter=0., vmax=M + (rng * high))
    normed = norm(s.values)
    c = [colors.rgb2hex(x) for x in plt.cm.get_cmap(cmap)(normed)]
    return ['background-color: %s' % color for color in c]

# x = df.apply(pd.to_numeric, errors='coerce')
df.style.apply(background_gradient,
               cmap=cmap,
               low=0.5,
               high=0.5, subset=pd.IndexSlice[:, ['B', 'C', 'D']],  axis=1
              )

在应用中使用axis=1(每行的列比较)


【讨论】:

规范中的 s 是什么(s.values) @AniketPatil: s 是你的 dataFrame df 的元素 通过 subset=pd.IndexSlice[:, ['B', 'C']] 检查编辑后的答案。您也可以使用此选项来选择行,或者只选择要传递的列,您可以将列名列表传递给子集。您可以根据需要修改此代码:) 我正在使用的 df 如图所示,它包含 str 数据以及股票行情,我试图修改我的代码,但无法获得所需的输出,我已经用代码更新了问题我正在使用 非常完整的答案!不错!

以上是关于根据数据框中单元格中的值将颜色应用于单元格的主要内容,如果未能解决你的问题,请参考以下文章

根据存储在其他单元格中的 RGB 值动态更改单元格的背景颜色

Pandas Dataframe 根据列值将值展平到单元格

如何将 CSV 值与 pyspark 数据框中的单元格中的值分别分隔为新列及其值

根据输入到单元格中的数字为单元格分配颜色和值,而无需点击运行按钮

如何根据多个单元格中的值自动填充

基于两个单元格的 Google 表格条件格式