December 1, 2022

Оформление стилей в Pandas

Надо перетерпеть те периоды, когда ваш стиль непопулярен, потому что если этот стиль хорош, он вернется, и все снова признают вашу красоту (Энди Уорхол).
Стилевое оформление датафрейма поможет сделать более наглядными особенности хранимых в нем данных, чтобы аналитик не упустил ничего интересного.

Сначала создадим демонстрационный датафрейм:

import pandas as pd
import numpy as np
df = pd.DataFrame({'col1':[100, 200.4, -300.234], 'col2':[50.55,-50,100]})
df

Область применения

Зона действия стиля может регулироваться используемыми методами. Например, applymap действует для каждого элемента датафрейма в отдельности. Метод принимает скаляр и для него возвращает css стиль (атрибут:значение):

df.style.applymap(lambda x: 'color:red' if x<0 else 'color:blue')

В отличие от него apply применяется к строкам или колонкам, соответственно, и правило стиля должно касаться множества элементов. Выделим минимум для каждой из строк:

df.style.apply(lambda x: ['color:green'  if v==x.min() else '' for v in x], axis=1)

C axis=None в apply можно применить функцию ко всему датафрейму. Но тогда и функция должна возвращать табличную структуру со стилями:

df.style.apply(lambda df: np.where(df==df.max().max(), 'background-color:yellow',''), axis=None)

Применение стилей можно комбинировать. Например, ниже мы выделяем и минимум в строке, и отрицательные числа:

df.style.apply(lambda x: ['background-color:yellow'  if v==x.min() else '' for v in x], axis=1)\
        .applymap(lambda x: 'color:red' if x<0 else 'color:blue')

С указанием аргумента subset, можно определить область, к которой применяется стиль:

df.style.apply(lambda x: ['background-color:green' for it in x], subset=['col2'], axis=1)
df.style.apply(lambda x: ['background-color:green' for it in x], subset=pd.IndexSlice[:1])
df.style.applymap(lambda x: 'color:blue' if x>0 else '', pd.IndexSlice[:1, ['col1', 'col2']])

Общие стили

Стиль в зависимости от значений

Используя метод background_gradient, можно присвоить существующий стиль числовому датафрейму в виде применения градиентных цветов в зависимости от значений в ячейках:

# df.style.background_gradient(cmap='viridis')
df.style.background_gradient()

Стиль вне зависимости от значений

Используйте метод set_properties:

df.style.set_properties(**{'background-color': 'grey',
                           'color': 'lawngreen',
                           'border-color': 'blue'})

Контроль отображаемых значений

Свойство стиль позволяет задавать и формат отображаемых значений:

df.style.format("{:.1f}")
df.style.format({'col1': "{:0<4.0f}", 'col2': '{:+.2f}'})

Строку формата можно получить и с использованием функции:

df.style.format({"col1": lambda x: f"±{abs(x):.2f}"})