Измените цвет текста в pandas таблице данных html html таблицы с использованием стилей и css

У меня есть pandas dataframe:

arrays = [['Midland', 'Midland', 'Hereford', 'Hereford', 'Hobbs','Hobbs', 'Childress',
           'Childress', 'Reese', 'Reese', 'San Angelo', 'San Angelo'],
          ['WRF','MOS','WRF','MOS','WRF','MOS','WRF','MOS','WRF','MOS','WRF','MOS']]
tuples = list(zip(*arrays))
index = pd.MultiIndex.from_tuples(tuples)
df = pd.DataFrame(np.random.randn(12, 4), index=arrays,
                  columns=['00 UTC', '06 UTC', '12 UTC', '18 UTC'])

Таблица, которая печатает df, выглядит следующим образом: введите описание изображения здесь

Я хотел бы пометить все значения в строках "MOS" определенным цветом и цветом в левых двух столбцах индекса/заголовка, а также в верхней строке заголовка другого цвета фона, чем остальные ячейки со значениями в их. Любые идеи, как я могу это сделать?

Ответ 1

Это занимает несколько шагов:

Первый импорт HTML и re

from IPython.display import HTML
import re

Вы можете получить HTML pandas с помощью метода to_html.

df_html = df.to_html()

Затем мы собираемся создать случайный идентификатор таблицы html и стиля, который мы собираемся создать.

random_id = 'id%d' % np.random.choice(np.arange(1000000))

Поскольку мы собираемся вставить какой-то стиль, нам нужно быть осторожным, чтобы указать, что этот стиль будет только для нашей таблицы. Теперь вставьте это в df_html

df_html = re.sub(r'<table', r'<table id=%s ' % random_id, df_html)

И создайте тег стиля. Это действительно зависит от вас. Я просто добавил эффект зависания.

style = """
<style>
    table#{random_id} tr:hover {{background-color: #f5f5f5}}
</style>
""".format(random_id=random_id)

Наконец, отобразите его

HTML(style + df_html)

Функция все в одном.

def HTML_with_style(df, style=None, random_id=None):
    from IPython.display import HTML
    import numpy as np
    import re

    df_html = df.to_html()

    if random_id is None:
        random_id = 'id%d' % np.random.choice(np.arange(1000000))

    if style is None:
        style = """
        <style>
            table#{random_id} {{color: blue}}
        </style>
        """.format(random_id=random_id)
    else:
        new_style = []
        s = re.sub(r'</?style>', '', style).strip()
        for line in s.split('\n'):
                line = line.strip()
                if not re.match(r'^table', line):
                    line = re.sub(r'^', 'table ', line)
                new_style.append(line)
        new_style = ['<style>'] + new_style + ['</style>']

        style = re.sub(r'table(#\S+)?', 'table#%s' % random_id, '\n'.join(new_style))

    df_html = re.sub(r'<table', r'<table id=%s ' % random_id, df_html)

    return HTML(style + df_html)

Используйте его следующим образом:

HTML_with_style(df.head())

введите описание изображения здесь

HTML_with_style(df.head(), '<style>table {color: red}</style>')

введите описание изображения здесь

style = """
<style>
    tr:nth-child(even) {color: green;}
    tr:nth-child(odd)  {color: aqua;}
</style>
"""
HTML_with_style(df.head(), style)

введите описание изображения здесь

Изучите CSS и сходите с ума!

Ответ 2

С помощью pandas новой стиля > функции (начиная с версии 0.17.1):

import numpy as np
import pandas as pd

arrays = [['Midland', 'Midland', 'Hereford', 'Hereford', 'Hobbs','Hobbs', 'Childress',
           'Childress', 'Reese', 'Reese', 'San Angelo', 'San Angelo'],
          ['WRF','MOS','WRF','MOS','WRF','MOS','WRF','MOS','WRF','MOS','WRF','MOS']]
tuples = list(zip(*arrays))
index = pd.MultiIndex.from_tuples(tuples)
df = pd.DataFrame(np.random.randn(12, 4), index=arrays,
                  columns=['00 UTC', '06 UTC', '12 UTC', '18 UTC'])


def highlight_MOS(s):
    is_mos = s.index.get_level_values(1) == 'MOS'
    return ['color: darkorange' if v else 'color: darkblue' for v in is_mos]

s = df.style.apply(highlight_MOS)
s

введите описание изображения здесь