aplicar el color a las células basado en el valor de la célula en el marco de datos

enter image description here

código de trabajo

 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)

Estaba recibiendo este error.

Archivo "c:\Users\91956\Desktop\asdf.py", línea 29, en m=df.min().min(), Archivo "C:\Users\91956\AppData\Local\Programas\Python\Python39\lib\site-packages\pandas\core\generic.py", línea 11468, en stat_func volver a sí mismo._reduce( Archivo "C:\Users\91956\AppData\Local\Programas\Python\Python39\lib\site-packages\pandas\core\series.py", línea 4248, en _reduce retorno op(delegate, skipna=skipna, **kwds) Archivo "C:\Users\91956\AppData\Local\Programas\Python\Python39\lib\site-packages\pandas\core\nanops.py", línea 129, en f resultado = alt(valores, axis=axis, skipna=skipna, **kwds) Archivo "C:\Users\91956\AppData\Local\Programas\Python\Python39\lib\site-packages\pandas\core\nanops.py", línea 873, en reducción resultado = getattr(valores, meth)(axis) Archivo "C:\Users\91956\AppData\Local\Programas\Python\Python39\lib\site-packages\numpy\core_methods.py", línea 43, en _amin devolver umr_minimum(a, axis, None, out, keepdims, initial, where) TipoError: 'consejo=' no soportado entre instancias de 'numpy.ndarray' y 'str '

actualización 2hizo los cambios necesarios. fue capaz de obtener la salida necesaria.

enter image description here

Pregunta hecha hace 3 años, 4 meses, 28 días - Por compilerczar


3 Respuestas:

  • Esto respuesta ayudará y también esto respuesta.

    Para crear la muestra 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']]
                  )
    

    enter image description here

    Editar:

    paso subset=pd.IndexSlice[:, ['B', 'C']] para aplicar - Quiero aplicar el color en B y C columna.

    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']]
                  )
    

    Edit2:

    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
                  )
    

    Uso axis=1 in apply (along column sabia comparison for each row)


    enter image description here

    Respondida el Dec 17, 2020 a las 13:25 - por cyberjedi

    Votos positivos: 0 | Votos negativos: 0

  • El error que estás recibiendo se produce porque estás tratando de comparar un array de NumPy con una cadena de texto en esta línea de código:

    python
    m = s.min()
    

    Para corregir este error, puedes modificar la función background_gradient para manejar correctamente los valores no numéricos. Puedes reemplazar esa línea con la siguiente modificación:

    python
    def background_gradient(s, cmap='PuBu', low=0, high=0):
        s = pd.to_numeric(s, errors='coerce') 
        m = s.min(skipna=True) 
        M = s.max(skipna=True) 
        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]
    

    Con estos cambios, deberías poder manejar los valores no numéricos de forma adecuada y evitar el error que estabas experimentando. Una vez realizados los cambios, prueba ejecutar el código nuevamente para verificar que funcione correctamente.

    Respondida el Dec 18, 2020 a las 13:29 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • Problema:

    El código anterior estaba generando un TypeError al intentar aplicar min() a un DataFrame con valores de cadena.

    Solución:

    Para resolver este problema, es necesario convertir los valores de cadena a numéricos antes de aplicar min(). Esto se puede hacer usando el método pd.to_numeric, como se muestra en el siguiente código actualizado:

    python
    import pandas as pd
    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., vp=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)

    Explicación:

    La línea s = pd.to_numeric(s, errors='coerce') convierte los valores de cadena en valores numéricos, manejando cualquier valor no numérico como NaN. El resto del código permanece igual.

    Salida:

    El código actualizado debería generar la salida HTML esperada con las celdas coloreadas según los valores de las celdas.

    Respondida el Dec 18, 2020 a las 13:35 - por Gemini

    Votos positivos: 0 | Votos negativos: 0