Обзор типов данных Pandas

Open in Colab


telegram

Введение

В процессе анализа данных важно убедиться, что вы используете правильные типы данных; в противном случае можете получить неожиданные результаты или ошибки. В этой статье будут обсуждаться основные типы данных pandas (также известные как dtypes), их сопоставление с типами данных Python и NumPy, а также варианты преобразования.

Оригинал статьи Криса тут.

Типы данных Pandas

Тип данных - это, по сути, внутреннее представление, которое язык программирования использует для понимания того, как данные хранить и как ими оперировать. Например, программа должна понимать, что вы хотите сложить два числа, например 5 + 10, чтобы получить 15. Или, если у вас есть две строки, такие как "кошка" и "шляпа" вы можете объединить (сложить) их вместе, чтобы получить "кошкашляпа".

Проблема с типами данных pandas заключается в том, что между pandas, Python и NumPy существует некоторое совпадение.

В следующей таблице приведены основные ключевые моменты:

Pandas Python NumPy Использование
object str или смесь string, unicode, смешанные типы Текстовые или смешанные числовые и нечисловые значения
int64 int int_, int8, int16, int32, int64, uint8, uint16, uint32, uint64 Целые числа
float64 float float_, float16, float32, float64 Числа с плавающей точкой
bool bool bool_ Значения True/False
datetime64 datetime datetime64[ns] Значения даты и времени
timedelta[ns] NA NA Разность между двумя datetimes
category NA NA Ограниченный список текстовых значений

В этом Блокноте я сосредоточусь на следующих типах данных pandas:

Про тип category смотрите в отдельной статье.

Тип данных object может фактически содержать несколько разных типов. Например, столбец a может включать целые числа, числа с плавающей точкой и строки, которые вместе помечаются как object. Следовательно, вам могут потребоваться некоторые дополнительные методы для обработки смешанных типов данных.

В этой статьетут перевод статьи на русский язык) вы найдете инструкцию по очистке данных, представленных ниже.

Почему нас это волнует?

Типы данных - одна из тех вещей, о которых вы, как правило, не заботитесь, пока не получите ошибку или неожиданные результаты. Это также одна из первых вещей, которую вы должны проверить после загрузки новых данных в pandas для дальнейшего анализа.

Я буду использовать очень простой CSV файл, чтобы проиллюстрировать пару распространенных ошибок, которые вы можете встретить.

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

Сложим продажи за 2016 и 2017 годы:

Выглядит странно. Мы хотели суммировать значения столбцов, но pandas их объединил, чтобы создать одну длинную строку.

Ключ к разгадке проблемы - это строка, в которой написано dtype: object.

object - это строка в pandas, поэтому он выполняет строковую конкатенацию вместо математического сложения.

Если мы хотим увидеть все типы данных, которые находятся в кадре данных (DataFrame), то воспользуемся атрибутом dtypes:

Кроме того, функция df.info() показывает много полезной информации:

После просмотра автоматически назначаемых типов данных возникает несколько проблем:

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

Чтобы преобразовать типы данных в pandas, есть три основных способа:

  • Используйте метод astype(), чтобы принудительно задать тип данных.
  • Создайте настраиваемую (custom) функцию для преобразования данных.
  • Используйте функции to_numeric() или to_datetime().

Использование функции astype()

Самый простой способ преобразовать столбец данных в другой тип - использовать astype(). Например, чтобы преобразовать Customer Number (Номер клиента) в целое число, можем сделать так:

Чтобы изменить Customer Number в исходном кадре данных, обязательно присвойте его обратно столбцу, так как функция astype() возвращает копию:

А вот новый кадр данных с Customer Number в качестве целого числа:

Все это выглядит хорошо и кажется довольно простым.

Давайте попробуем проделать то же самое со столбцом 2016 и преобразовать его в число с плавающей точкой:

Аналогичным образом мы можем попытаться преобразовать столбец Jan Units в целое число:

Оба примера возвращают исключения ValueError, т.е. преобразования не сработали.

В каждом из случаев данные включали значения, которые нельзя было интерпретировать как числа. В столбцах продаж данные включают символ валюты $, а также запятую. В столбце Jan Units последним значением является Closed (Закрыто), которое не является числом; так что мы получаем исключение.

Пока что astype() как инструмент для преобразования выглядит не очень хорошо.

Мы должны попробовать еще раз в столбце Active.

На первый взгляд все выглядит нормально, но при ближайшем рассмотрении обнаруживается проблема. Все значения были интерпретированы как True, но последний клиент в столбце Active имеет флаг N вместо Y.

Вывод из этого раздела такой - astype() будет работать, если:

Если данные содержат нечисловые символы или неоднородны, то astype() будет плохим выбором для преобразования типов. Вам потребуется выполнить дополнительные преобразования, чтобы изменение типа работало правильно.

Дополнительно

Отметим, что astype() может принимать словарь имен столбцов и типов данных:

Пользовательские функции преобразования

Поскольку эти данные немного сложнее преобразовать, можно создать настраиваемую (custom) функцию, которую применим к каждому значению и преобразовать в соответствующий тип данных.

Для конвертации валюты (этого конкретного набора данных) мы можем использовать простую функцию:

В коде используются строковые функции Python, чтобы очистить символы $ и ,, а затем преобразовать значение в число с плавающей точкой. В этом конкретном случае мы могли бы преобразовать значения в целые числа, но я предпочитаю использовать плавающую точку.

Я также подозреваю, что кто-нибудь рекомендует использовать тип данных Decimal для валюты. Это не встроенный тип в pandas, поэтому я намеренно придерживаюсь подхода с плавающей точкой.

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

Теперь мы можем использовать функцию apply, чтобы применить ее ко всем значениям в столбце 2016.

Успех! Все значения отображаются как float64, поэтому мы можем выполнять необходимые математические функции.

Я уверен, что более опытные читатели спрашивают, почему я просто не использовал лямбда-функцию?

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

Используя lambda, мы можем упростить код до одной строки, что является совершенно правильным подходом. Этот подход вызывает у меня три основных опасения:

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

Вот полный пример преобразования данных в обоих столбцах продаж с помощью функции convert_currency.

В качестве другого примера использования lambda против функции мы можем взглянуть на процесс исправления столбца Percent Growth.

Используя lambda:

То же самое и с пользовательской функцией:

Последняя настраиваемая функция, о которой я расскажу, использует np.where() для преобразования столбца Active в логическое значение.

Основная идея состоит в том, чтобы использовать функцию np.where() для преобразования всех значений Y в True, а всему остальному назначить False.

В результате получается следующий кадр данных:

Для dtype правильно установлено значение bool.

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

Вспомогательные функции pandas

У pandas есть золотая середина между простой функцией astype() и более сложными пользовательскими функциями. Эти вспомогательные функции могут быть очень полезны для преобразования определенных типов данных.

Если вы следовали инструкциям, вы заметите, что я ничего не делал с столбцами даты или столбцом Jan Units. Оба столбца могут быть преобразованы с помощью встроенных в pandas функций, таких как pd.to_numeric() и pd.to_datetime().

Причина, по которой преобразование Jan Units проблематично, заключается в том, что в столбце содержится нечисловое значение. Если бы мы попытались использовать astype(), то получили бы ошибку (как описано ранее). Функция pd.to_numeric() может обрабатывать эти значения более изящно:

Следует отметить несколько моментов. Во-первых, функция легко обрабатывает данные и создает столбец float64. Кроме того, она заменяет недопустимое значение Closed на значение NaN, потому что мы передали аргумент errors=coerce. Мы можем оставить это значение там или заполнить его 0 с помощью fillna(0):

Последнее преобразование, о котором я расскажу, - это преобразование отдельных столбцов месяца, дня и года в тип datetime. Функцию pd.to_datetime() можно настраивать, но по умолчанию она также довольно умна.

В этом случае функция объединяет столбцы в новую серию, соответствующую типу datateime64.

Мы должны убедиться, что присвоили эти значения обратно кадру данных:

Теперь данные правильно преобразованы во все нужные нам типы:

Кадр данных готов к анализу!

Собираем все вместе

Основные концепции использования astype() и пользовательских функций могут быть включены на очень раннем этапе процесса анализа данных. Если у вас есть файл с данными, который вы собираетесь обрабатывать повторно, и он всегда имеет один и тот же формат, вы можете задать параметры dtype и converters, которые будут применяться при чтении данных. Полезно думать о dtype как о выполнении функции astype() для данных. Аргументы converters позволяют применять функции к различным входным столбцам аналогично подходам, описанным выше.

Важно отметить, что вы можете применить dtype или функцию converter к указанному столбцу только один раз, используя этот подход. Если вы попытаетесь применить оба к одному столбцу, то dtype будет пропущен.

Вот упрощенный пример, который выполняет почти все преобразования во время считывания данных:

Как упоминалось ранее, я решил включить пример lambda, а также пример функции для преобразования данных. Единственная функция, которую здесь нельзя применить, - это преобразование столбцов Month, Day и Year в соответствующий столбец datetime. Тем не менее, это мощное соглашение, которое может помочь улучшить конвейер обработки данных.

Резюме

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