5 Расширенных возможностей Pandas и как ими пользоваться


Pandas — это золотой стандарт в обработке данных. А функциональные возможности библиотеки по загрузке, фильтрации, обработке и изучению данных быстро сделали ее излюбленным инструментом аналитиков.

Конечно же, большинство из нас работает с самыми примитивными возможностями: загрузка данных из CSV-файла, фильтр нескольких столбцов и переход к визуализации данных. Однако в Pandas есть и малоизвестные, но от того не менее полезные функции, которые значительно упрощают обработку данных.

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

(1) Настройка опций и параметров

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

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

import pandas as pd display_settings = { 'max_columns': 10, 'expand_frame_repr': True, # Развернуть на несколько страниц 'max_rows': 10, 'precision': 2, 'show_dimensions': True } for op, value in display_settings.items(): pd.set_option("display.{}".format(op), value)

В коде выше показывается, что Pandas может отображать не более 10 строк и 10 столбцов, а максимально допустимое количество знаков после запятой — 2. Таким образом, при добавлении большого DataFrame в терминал или Jupyter Notebook, он не превратится в мешанину из данных.

Это лишь базовый пример. Существует куда больше полезных возможностей Pandas. Почитать о других опциях можно в официальной документации.

(2) Объединение DataFrame

Мало кто знает, что DataFrame в Pandas можно объединить несколькими способами. Каждый из этих способов выдает разный результат, поэтому при выборе руководствуйтесь собственными целями. Кроме того, в оба способа заложены наборы параметров для более глубокой настройки слияния. Давайте поговорим о них подробнее.

Конкатенация

Конкатенация относится к самым известным методам объединения фреймов данных; ее можно рассматривать, как «стекинг». И этот самый стекинг бывает вертикальным или горизонтальным.

К примеру, у вас есть огромный набор данных в CSV-формате, и для упрощения обработки имеет смысл разделить его на несколько файлов. Это весьма распространенная практика для огромных наборов данных и довольно часто она называется «фрагментацией» или «шардингом».

При загрузке данных в Pandas вы можете создать единый DataFrame с помощью вертикальной пристыковки фрейма данных из каждого CSV-файла. Предположим, у нас есть 3 фрагмента по 5 миллионов строк в каждом. Тогда после вертикального стекинга наш итоговый фрейм данных будет содержать 15 миллионов строк.

В коде ниже показана вертикальная конкатенация DataFrame в Pandas.

# Вертикальная конкатенацияpd.concat([october_df, november_df, december_df], axis=0)

Похожий результат можно получить при разделении набора данных не по строкам, а по столбцам. В таком случае, из каждого CSV-файла берется по нескольку столбцов со всеми строками. Это чем-то похоже на фрагментацию наборов данных по признакам. Далее выполняется горизонтальный стекинг для объединения столбцов/признаков.

# Горизонтальная конкатенацияpd.concat([features_1to5_df, features_6to10_df, features_11to15_df], axis=1) Слияние

Слияние — это более сложный и мощный тип объединения DataFrame в стиле SQL. Фреймы данных объединяются по какому-то общему атрибуту.

Допустим, у вас есть два DataFrame с описанием YouTube-канала. Один из фреймов — это список ID пользователей и общее количество времени, которое каждый пользователь провел на канале. Другой фрейм содержит тот же список с ID и количество просмотренных роликов по каждому пользователю. Благодаря слиянию мы сможем объединить два фрейма данных в один по ID пользователя, а затем добавим туда единой строкой ID, затраченное время и количество просмотренных роликов.

Слияние двух DataFrame в Pandas делается через функцию merge. Пример ее использования можно найти ниже. Параметры left и right задают два DataFrame для объединения, а в on отмечается столбец для сопоставления данных.

pd.merge(left=ids_and_time_df, right=ids_and_videos_df, on="id")

Чтобы еще качественнее имитировать SQL-объединение, воспользуйтесь параметром how. Он позволяет выбрать тип SQL-объединения: внутреннее, внешнее, слева или справа. Подробнее об SQL-объединениях читайте на W3Schools.

(3) Изменение формы DataFrame

Существует несколько способов изменения формы и структуры фреймов данных в Pandas. От простых и легких до мощных и сложных. Давайте рассмотрим три наиболее популярные разновидности. Во всех примерах мы будем работать с набором данных о супергероях.

import pandas as pd players_data = {'Player': ['Superman', 'Batman', 'Thanos', 'Batman', 'Thanos', 'Superman', 'Batman', 'Thanos', 'Black Widow', 'Batman', 'Thanos', 'Superman'], 'Year': [2000,2000,2000,2001,2001,2002,2002,2002,2003,2004,2004,2005], 'Points':[23,43,45,65,76,34,23,78,89,76,92,87]} df = pd.DataFrame(players_data) print(df) """ Player Year Points 0 Superman 2000 23 1 Batman 2000 43 2 Thanos 2000 45 3 Batman 2001 65 4 Thanos 2001 76 5 Superman 2002 34 6 Batman 2002 23 7 Thanos 2002 78 8 Black Widow 2003 89 9 Batman 2004 76 10 Thanos 2004 92 Транспонирование

Простейший способ. Здесь мы заменяем строки DataFrame на столбцы. Если у вас есть 5 000 строк и 10 столбцов, то после транспонирования вы получите 10 строк и 5 000 столбцов.

import pandas as pd players_data = {'Player': ['Superman', 'Batman', 'Thanos', 'Batman', 'Thanos', 'Superman', 'Batman', 'Thanos', 'Black Widow', 'Batman', 'Thanos', 'Superman'], 'Year': [2000,2000,2000,2001,2001,2002,2002,2002,2003,2004,2004,2005], 'Points':[23,43,45,65,76,34,23,78,89,76,92,87]} df = pd.DataFrame(players_data) print(df) """ Player Year Points 0 Superman 2000 23 1 Batman 2000 43 2 Thanos 2000 45 3 Batman 2001 65 4 Thanos 2001 76 5 Superman 2002 34 6 Batman 2002 23 7 Thanos 2002 78 8 Black Widow 2003 89 9 Batman 2004 76 10 Thanos 2004 92 11 Superman 2005 87 """ Groupby

Основное назначение Groupby — это разделение фреймов данных на части по определенным ключам. После разделения DataFrame вы сможете пройтись циклом по каждой из частей или выполнить дополнительные действия.

Например, в коде ниже мы создали фрейм данных по игрокам с их стажем (Years) и количеством очков (Points). Затем с помощью groupby мы разделили DataFrame на несколько частей по полю «игрок» (Player). Таким образом, каждый игрок оказался в собственной группе, показывающей, сколько очков данный игрок набрал за каждый год активности.

groups_df = df.groupby('Player') for player, group in groups_df: print("----- {} -----".format(player)) print(group) print("") ### Это выводит следующее """ ----- Batman ----- Player Year Points 1 Batman 2000 43 3 Batman 2001 65 6 Batman 2002 23 9 Batman 2004 76 ----- Black Widow ----- Player Year Points 8 Black Widow 2003 89 ----- Superman ----- Player Year Points 0 Superman 2000 23 5 Superman 2002 34 11 Superman 2005 87 ----- Thanos ----- Player Year Points 2 Thanos 2000 45 4 Thanos 2001 76 7 Thanos 2002 78 10 Thanos 2004 92 """ Стекинг

Стекинг в Pandas— это способ преобразования фреймов данных, при котором в DataFrame появляется многоуровневый индекс, т.е. каждая строка разбивается на несколько частей. Эти части создаются из столбцов DataFrame с дальнейшим сжатием их в мультииндекс. В общем и целом, стекинг можно рассматривать как сжатие столбцов в строки с мультииндексом.

Лучше всего все это показано в коде ниже.

df = df.stack() print(df) """ 0 Player Superman Year 2000 Points 23 1 Player Batman Year 2000 Points 43 2 Player Thanos Year 2000 Points 45 3 Player Batman Year 2001 Points 65 4 Player Thanos Year 2001 Points 76 5 Player Superman Year 2002 Points 34 6 Player Batman Year 2002 Points 23 7 Player Thanos Year 2002 Points 78 8 Player Black Widow Year 2003 Points 89 9 Player Batman Year 2004 Points 76 10 Player Thanos Year 2004 Points 92 11 Player Superman Year 2005 Points 87 """

(4) Работа с данными о дате и времени

Библиотека Datetime — это неотъемлемая часть Python. Всякий раз, встретив данные о дате или времени, вы обращаетесь к Datetime. К счастью для нас, Pandas придумала собственные возможности для использования объектов Datetime.

Давайте рассмотрим их на примере. В коде ниже мы создаем DataFrame с 4 столбцами (день, месяц, год, нужные данные), а затем сортируем их по году и месяцу. Как видите, получается слишком громоздко: для хранения данных используется целых 3 столбца, тогда как по факту календарная дата — это всего лишь одно значение.

from itertools import product import pandas as pd import numpy as np col_names = ["Day", "Month", "Year"] df = pd.DataFrame(list(product([10, 11, 12], [8, 9], [2018, 2019])), columns=col_names) df['data'] = np.random.randn(len(df)) df = df.sort_values(['Year', 'Month'], ascending=[True, True]) print(df) """ Day Month Year data 0 10 8 2018 1.685356 4 11 8 2018 0.441383 8 12 8 2018 1.276089 2 10 9 2018 -0.260338 6 11 9 2018 0.404769 10 12 9 2018 -0.359598 1 10 8 2019 0.145498 5 11 8 2019 -0.731463 9 12 8 2019 -1.451633 3 10 9 2019 -0.988294 7 11 9 2019 -0.687049 11 12 9 2019 -0.067432 """

Навести здесь порядок нам поможет datetime.

Pandas придумала отличную функцию to_datetime(), которая сжимает несколько столбцов DataFrame и преобразует их в единый объект Datetime. Сразу при задании нужного формата нам становятся доступны все гибкие возможности библиотеки Datetime.

Чтобы воспользоваться функцией to_datetime(), передадим ей все данные о дате из соответствующих столбцов (Day, Month, Year). После преобразования этих данных в формат Datetime, остальные столбцы нам больше не потребуются. Если хотите, можете от них избавиться. Вот, как все работает:

from itertools import product import pandas as pd import numpy as np col_names = ["Day", "Month", "Year"] df = pd.DataFrame(list(product([10, 11, 12], [8, 9], [2018, 2019])), columns=col_names) df['data'] = np.random.randn(len(df)) df = df.sort_values(['Year', 'Month'], ascending=[True, True]) df.insert(loc=0, column="date", value=pd.to_datetime(df[col_names])) df = df.drop(col_names, axis=1).squeeze() print(df) """ date data 0 2018-08-10 -0.328973 4 2018-08-11 -0.670790 8 2018-08-12 -1.360565 2 2018-09-10 -0.401973 6 2018-09-11 -1.238754 10 2018-09-12 0.957695 1 2019-08-10 0.571126 5 2019-08-11 -1.320735 9 2019-08-12 0.196036 3 2019-09-10 -1.717800 7 2019-09-11 0.074606 11 2019-09-12 -0.643198 """

(5) Классификация элементов по группам

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

Взгляните на код ниже. Здесь приводится список продуктов, которые хотелось бы классифицировать:

import pandas as pd foods = pd.Series(["Bread", "Rice", "Steak", "Ham", "Chicken", "Apples", "Potatoes", "Mangoes", "Fish", "Bread", "Rice", "Steak", "Ham", "Chicken", "Apples", "Potatoes", "Mangoes", "Fish", "Apples", "Potatoes", "Mangoes", "Fish", "Apples", "Potatoes", "Mangoes", "Fish", "Bread", "Rice", "Steak", "Ham", "Chicken", "Bread", "Rice", "Steak", "Ham", "Chicken", "Bread", "Rice", "Steak", "Ham", "Chicken", "Apples", "Potatoes", "Mangoes", "Fish", "Apples", "Potatoes", "Mangoes", "Fish", "Apples", "Potatoes", "Mangoes", "Fish", "Bread", "Rice", "Steak", "Ham", "Chicken", "Bread", "Rice", "Steak", "Ham", "Chicken",]) groups_dict = { "Protein": ["Steak", "Ham", "Chicken", "Fish"], "Carbs": ["Bread", "Rice", "Apples", "Potatoes", "Mangoes"] }

Здесь мы выносим наш список в Series и создаем словарь с нужной нам классификацией Protein или Carbs. Это простейший пример. Но если бы эта Series была достаточно крупной (например, в 1 000 000 элементов длиной), то прохождение по ней циклом оказалось бы совершенно не разумным решением.

В таком случае, вместо обычного цикла for, лучше написать отдельную функцию, которая будет использовать встроенную Pandas-функцию map()для оптимизации процесса. В коде ниже все подробно расписано.

def membership_map(pandas_series, groups_dict): groups = {x: k for k, v in groups_dict.items() for x in v} mapped_series = pandas_series.map(groups) return mapped_series mapped_data = membership_map(foods, groups_dict) print(list(mapped_data))

В этой функции мы проходимся циклом по всему словарю и создаем новый словарь, в котором ключами служат все вариации элементов из Series, а значениями являются признаки Protein или Carbs. Далее мы просто применяем встроенную функцию map() и классифицируем все значения из Series.

Вот, что у нас получается:

['Carbs', 'Carbs', 'Protein', 'Protein', 'Protein', 'Carbs', 'Carbs', 'Carbs', 'Protein', 'Carbs', 'Carbs', 'Protein', 'Protein', 'Protein', 'Carbs', 'Carbs', 'Carbs', 'Protein', 'Carbs', 'Carbs', 'Carbs', 'Protein', 'Carbs', 'Carbs', 'Carbs', 'Protein', 'Carbs', 'Carbs', 'Protein', 'Protein', 'Protein', 'Carbs', 'Carbs', 'Protein', 'Protein', 'Protein', 'Carbs', 'Carbs', 'Protein', 'Protein', 'Protein', 'Carbs', 'Carbs', 'Carbs', 'Protein', 'Carbs', 'Carbs', 'Carbs', 'Protein', 'Carbs', 'Carbs', 'Carbs', 'Protein', 'Carbs', 'Carbs', 'Protein', 'Protein', 'Protein', 'Carbs', 'Carbs', 'Protein', 'Protein', 'Protein']

Заключение

Вот и все. Теперь вы узнали о 5 продвинутых возможностях Pandas и вариантах их применения.


Перевод статьи George Seif: 5 Advanced Features of Pandas and How to Use Them


Поделиться статьей:


Вернуться к статьям

Комментарии

    Ничего не найдено.