Как стать автором
Обновить

Формат таблиц в pandas

Время на прочтение4 мин
Количество просмотров67K

Если вы пока ещё не знаете как транслировать данные напрямую заказчику в подсознание или, на худой конец, текст сообщения в slack, вам пригодится информация о том, как сделать процесс интерпретации таблиц более быстрым и комфортным.


Например, в excel для этого используется условное форматирование и спарклайны. А в этой статье мы посмотрим как визуализировать данные с помощью Python и библиотеки pandas: будем использовать свойства DataFrame.style и Options and settings.


Настраиваем базовую визуализацию


Импортируем библиотеки: pandas для работы с данными и seaborn для загрузки классического набора данных penguins:


import pandas as pd
import seaborn as sns

С помощью pd.set_option настроим вывод так чтобы:


  • количество строк в таблице было не больше 5;
  • текст в ячейке отражался полностью вне зависимости от длины (это удобно, если в ячейке длинный заголовок или URL, которые хочется посмотреть);
  • все числа отражались с двумя знаками после запятой;

pd.set_option('max_rows', 5)
pd.set_option('display.max_colwidth', None)
pd.set_option('display.float_format', '{:.2f}'.format)

Прочитаем и посмотрим датафрейм.


penguins = sns.load_dataset(‘penguins’)
penguins

image


Если нужно вернуть настройки к дефолтным, используем pd.reset_option. Например, так, если хотим обновить все настройки разом:


pd.reset_option('all')

Полный список свойств set_option.


Настраиваем отображение данных в таблицах


Формат чисел, пропуски и регистр


У датафреймов в pandas есть свойство DataFrame.style, которое меняет отображение содержимого ячеек по условию для строк или столбцов.


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


(penguins
 .head(5)
 .style
 .format('{:.1f}', na_rep='-')
 .format({'species': lambda x:x.lower(),
          'island': lambda x:x.lower(),
          'sex': lambda x: '-' if pd.isna(x) else x.lower()
         })
)

image


У нас тут всё про пингвинов, но в данные о ценах, можно добавить знак ₽ перед числом таким образом:


(df
.style
.format({'price': '₽{:.2f}'})
)

Дальше — больше!


Выделение цветом (минимум, максимум, пропуски)


Функции для поиска минимального и максимального значений не работают с текстовыми полями, поэтому заранее выделим столбцы, для которых они будут применяться, в отдельный список. Этот список будем передавать в параметр subset.


numeric_columns = ['bill_length_mm',
                   'bill_depth_mm',
                   'flipper_length_mm',
                   'body_mass_g']

Подсветим минимум, максимум и пустые ячейки и выведем первые 5 строк датафрейма.


(penguins
 .head(5)
 .style
 .format('{:.1f}', na_rep='-')
 .format({'species': lambda x:x.lower(),
          'island': lambda x:x.lower(),
          'sex': lambda x: '-' if pd.isna(x) else x.lower()
         })
 .highlight_null(null_color='lightgrey')
 .highlight_max(color='yellowgreen', subset=numeric_columns)
 .highlight_min(color='coral', subset=numeric_columns)
)

image


Наглядно видно, что в этих 5ти строках самый длинный клюв у пингвина в строке с индексом 2 и у него (неё!) же самые длинные плавники и самый маленький вес.


Усложним ещё немного: посмотрим на разброс длины плавников пингвинов-девочек вида Adelie.


Bar chart в таблице


Для начала, выделим в отдельный датафрейм пингвинов женского пола и вида Adelie и посчитаем для них разброс длин плавников.


adelie_female = (penguins[(penguins['species'] == 'Adelie') & 
                          (penguins['sex'] == 'FEMALE')]
                 .copy()
                )

adelie_female['flipper_l_var'] = ((adelie_female['flipper_length_mm']- 
                                                 adelie_female['flipper_length_mm'].mean()).round())

К форматированию числовых значений, пропусков и регистра добавляем формат для столбца 'flipper_l_var'. Задаём:


  • группу столбцов (subset), для которых будем строить график;
  • выравнивание (align): mid — так как мы ожидаем, что значения будут как положительные, так и отрицательные. Подробнее про другие параметры выравнивания можно посмотреть тут;
  • цвет (color). В нашем случае 2 цвета: для отрицательных и положительных значений;
  • границы (vmin, vmax).

Отдельно с помощью set_properties пропишем, что значения в столбце 'flipper_l_var' должны стоять в центре ячейки.


(adelie_female
 .head(5)
 .style
 .format('{:.1f}', na_rep='-')
 .format({'species': lambda x:x.lower(),
          'island': lambda x:x.lower(),
          'sex': lambda x: '-' if pd.isna(x) else x.lower()
         })
 .bar(subset=['flipper_l_var'],
      align='mid',
      color=['coral', 'yellowgreen'],
      vmin=adelie_female['flipper_l_var'].min(),
      vmax=adelie_female['flipper_l_var'].max()
     )
 .set_properties(**{'text-align': 'center'}, subset='flipper_l_var')
)

image


Heatmap в таблице


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


Посчитаем количество пингвинов разных видов и средние значения массы, длин плавников и клюва в зависимости от вида.


species_stat=(penguins
             .groupby('species')
             .agg(penguins_count=('species','count'),
                  mean_bill_length=('bill_length_mm', 'mean'),
                  mean_bill_depth=('bill_depth_mm', 'mean'),
                  mean_flipper_length=('flipper_length_mm', 'mean'),
                  mean_body_mass=('body_mass_g', 'mean'),
                 )
             )

image


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


Исправим это. Потому что, ну что может быть полезнее и веселее разглядывания чисел?! И если вы думаете по-другому, я не знаю, зачем вы дочитали до этого момента.


(species_stat
 .T
 .style
 .format("{:.1f}")
 .background_gradient(cmap='Blues', axis=1)
)

image


Транспонируем таблицу — так нагляднее сравнение между видами и применяем метод background_gradient со следующими параметрами:


  • цветовая карта(cmap): Blues. Это одна из дефолтных карт;
  • сравнение по строкам (axis=1).

Вывод


Форматирование таблиц в pandas с помощью DataFrame.style и Options and settings упрощает жизнь, ну или как минимум улучшает читабельность кода и отчетов. Но обработку типов данных, пропусков и регистра лучше, конечно, проводить осознанно ещё до этапа визуализации.


Дополнительно можно разобраться с:


Теги:
Хабы:
Всего голосов 13: ↑13 и ↓0+13
Комментарии14

Публикации

Истории

Работа

Python разработчик
118 вакансий
Data Scientist
80 вакансий

Ближайшие события

7 – 8 ноября
Конференция byteoilgas_conf 2024
МоскваОнлайн
7 – 8 ноября
Конференция «Матемаркетинг»
МоскваОнлайн
15 – 16 ноября
IT-конференция Merge Skolkovo
Москва
22 – 24 ноября
Хакатон «AgroCode Hack Genetics'24»
Онлайн
28 ноября
Конференция «TechRec: ITHR CAMPUS»
МоскваОнлайн
25 – 26 апреля
IT-конференция Merge Tatarstan 2025
Казань