Освоение искусства очистки данных в Python

Освоение искусства очистки данных в Python – KDnuggets

Исходный узел: 2939047

Освоение искусства очистки данных в Python
Изображение по автору
 

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

В этой статье вы познакомитесь с несколькими ключевыми методами очистки данных в Python с использованием мощных библиотек, таких как pandas, numpy, seaborn и matplotlib.

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

Мы рассмотрим следующие задачи очистки данных.
 

Освоение искусства очистки данных в Python
Изображение по автору

Прежде чем начать, давайте импортируем необходимые библиотеки. Мы будем использовать pandas для манипулирования данными, а также seaborn и matplotlib для визуализации.

Мы также импортируем модуль Python datetime для управления датами.

import pandas as pd
import seaborn as sns
import datetime as dt
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker

Сначала нам нужно загрузить наши данные. В этом примере мы собираемся загрузить CSV-файл с помощью pandas. Мы также добавляем аргумент-разделитель.

df = pd.read_csv('F:KDNuggetsKDN Mastering the Art of Data Cleaning in Pythonproperty.csv', delimiter= ';')

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

# Look at all the rows of the dataframe
display(df)

Вот как выглядит набор данных.

 

Освоение искусства очистки данных в Python
 

Вы сразу увидите, что некоторые пропущенные значения. Кроме того, форматы дат несовместимы.

Теперь давайте посмотрим на сводку DataFrame с помощью метода info().

# Get a concise summary of the dataframe
print(df.info())

Вот вывод кода.

 

Освоение искусства очистки данных в Python
 

Мы видим, что только столбец Square_feet не имеет значений NULL, поэтому нам придется как-то с этим справиться. Кроме того, столбцы Advertise_date и Sale_date представляют собой тип данных объекта, хотя это должна быть дата.

Местоположение столбца совершенно пустое. Нам это нужно?

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

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

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

Мы используем метод drop() с указанным именем столбца. Мы устанавливаем ось на 1, чтобы указать, что мы хотим удалить столбец. Кроме того, для аргумента inplace установлено значение True, чтобы мы могли изменить существующий DataFrame, а не создавать новый DataFrame без удаленного столбца.

df.drop('buyer', axis = 1, inplace = True)

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

Мы используем тот же подход, что и в первом столбце.

df.drop('location', axis = 1, inplace = True)

Конечно, вы можете удалить эти два столбца одновременно.

df = df.drop(['buyer', 'location'], axis=1)

Оба подхода возвращают следующий кадр данных.

 

Освоение искусства очистки данных в Python

Дублирующиеся данные могут возникнуть в вашем наборе данных по разным причинам и могут исказить ваш анализ.

Давайте обнаружим дубликаты в нашем наборе данных. Вот как это сделать.

В приведенном ниже коде используется метод дублируется() для рассмотрения дубликатов во всем наборе данных. Его настройка по умолчанию — считать первое появление значения уникальным, а последующие — дубликатами. Вы можете изменить это поведение, используя держать параметр. Например, df.duulated(keep=False) пометит все дубликаты как True, включая первое вхождение.

# Detecting duplicates
duplicates = df[df.duplicated()]
duplicates

Вот результат.

 

Освоение искусства очистки данных в Python
 

Строка с индексом 3 помечена как повторяющаяся, поскольку строка 2 с такими же значениями встречается впервые.

Теперь нам нужно удалить дубликаты, что мы и делаем с помощью следующего кода.

# Detecting duplicates
duplicates = df[df.duplicated()]
duplicates

Ассоциация drop_duplications() функция учитывает все столбцы при выявлении дубликатов. Если вы хотите учитывать только определенные столбцы, вы можете передать их в виде списка в эту функцию следующим образом: df.drop_duulates(subset=['column1', 'column2']).

 

Освоение искусства очистки данных в Python
 

Как видите, повторяющаяся строка удалена. Однако индексация осталась прежней, индекс 3 отсутствовал. Мы исправим это, сбросив индексы.

df = df.reset_index(drop=True)

Эта задача выполняется с помощью сброс_индекс() функция. Аргумент drop=True используется для отбрасывания исходного индекса. Если вы не включите этот аргумент, старый индекс будет добавлен как новый столбец в вашем DataFrame. Установив drop=True, вы говорите пандам забыть старый индекс и сбросить его до целочисленного индекса по умолчанию.

Для практики попробуйте удалить дубликаты из этого набора данных Microsoft.

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

В нашем наборе данных мы сделаем это для столбцов реклама_дата и продажа_дата, поскольку они показаны как тип данных объекта. Кроме того, даты в строках форматируются по-разному. Нам нужно сделать его согласованным, а также преобразовать его в актуальное состояние.

Самый простой способ - это использовать to_datetime() метод. Опять же, вы можете сделать это столбец за столбцом, как показано ниже.

При этом мы устанавливаем для аргумента dayfirst значение True, поскольку некоторые даты начинаются с первого дня.

# Converting advertisement_date column to datetime
df['advertisement_date'] = pd.to_datetime(df['advertisement_date'], dayfirst = True) # Converting sale_date column to datetime
df['sale_date'] = pd.to_datetime(df['sale_date'], dayfirst = True)

Вы также можете преобразовать оба столбца одновременно, используя применять() метод с to_datetime().

# Converting advertisement_date and sale_date columns to datetime
df[['advertisement_date', 'sale_date']] = df[['advertisement_date', 'sale_date']].apply(pd.to_datetime, dayfirst = True)

Оба подхода дают одинаковый результат.

 

Освоение искусства очистки данных в Python
 

Теперь даты имеют единый формат. Мы видим, что не все данные были преобразованы. В Advertise_date имеется одно значение NaT, а в sale_date — два. Это означает, что дата отсутствует.

Давайте проверим, преобразуются ли столбцы в даты, используя команду Информация() метод.

# Get a concise summary of the dataframe
print(df.info())

 

Освоение искусства очистки данных в Python
 

Как видите, оба столбца не имеют формата datetime64[ns].

Теперь попробуйте преобразовать данные из TEXT в NUMERIC в этом Набор данных Airbnb.

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

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

Удаление строк с отсутствующими значениями

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

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

Вот код, в котором мы указываем индекс строки.

df = df.drop(8)

DataFrame теперь выглядит так.

 

Освоение искусства очистки данных в Python
 

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

Вменение пропущенных значений

Если у вас есть значительные недостающие данные, лучшей стратегией, чем удаление, может быть вменение. Этот процесс включает в себя заполнение пропущенных значений на основе других данных. Для числовых данных распространенные методы вменения включают использование меры центральной тенденции (среднее значение, медиана, мода).

В нашем уже измененном DataFrame у нас есть значения NaT (Not a Time) в столбцах Advertise_date и sale_date. Мы вменим эти недостающие значения, используя значит() метод.

В коде используется заполнить () метод для поиска и заполнения нулевых значений средним значением.

# Imputing values for numerical columns
df['advertisement_date'] = df['advertisement_date'].fillna(df['advertisement_date'].mean())
df['sale_date'] = df['sale_date'].fillna(df['sale_date'].mean())

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

# Imputing values for multiple numerical columns
df[['advertisement_date', 'sale_date']] = df[['advertisement_date', 'sale_date']].apply(lambda x: x.fillna(x.mean()))

Результат в обоих случаях выглядит следующим образом.

 

Освоение искусства очистки данных в Python
 

В нашем столбце sale_date теперь указано время, которое нам не нужно. Давайте удалим их.

Мы будем использовать strftime () метод, который преобразует даты в их строковое представление и определенный формат.

df['sale_date'] = df['sale_date'].dt.strftime('%Y-%m-%d')

 

Освоение искусства очистки данных в Python
 

Даты теперь выглядят аккуратно.

Если вам нужно использовать strftime () в нескольких столбцах вы снова можете использовать лямбда следующим образом.

df[['date1_formatted', 'date2_formatted']] = df[['date1', 'date2']].apply(lambda x: x.dt.strftime('%Y-%m-%d'))

Теперь давайте посмотрим, как мы можем приписать недостающие категориальные значения.

Категориальные данные — это тип данных, который используется для группировки информации со схожими характеристиками. Каждая из этих групп представляет собой категорию. Категориальные данные могут принимать числовые значения (например, «1» означает «мужчина» и «2» означает «женщина»), но эти числа не имеют математического значения. Например, вы не можете сложить их вместе.

Категориальные данные обычно делятся на две категории:

  1. Номинальные данные: Это когда категории только помечены и не могут быть расположены в каком-либо определенном порядке. Примеры включают пол (мужской, женский), группу крови (A, B, AB, O) или цвет кожи (красный, зеленый, синий).
  1. Порядковые данные: Здесь категории можно упорядочить или ранжировать. Хотя интервалы между категориями не одинаковы, порядок категорий имеет значение. Примеры включают рейтинговые шкалы (оценка фильма от 1 до 5), уровень образования (средняя школа, бакалавриат, аспирант) или стадии рака (стадия I, стадия II, стадия III).

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

Заменим пропущенные значения на mode.

# For categorical columns
df['property_category'] = df['property_category'].fillna(df['property_category'].mode()[0])

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

Кроме того, часть [0] используется для извлечения первого значения из этой серии. Если существует несколько режимов, будет выбран первый. Если есть только один режим, он все равно работает нормально.

Вот результат.

 

Освоение искусства очистки данных в Python
 

Данные теперь выглядят довольно хорошо. Остается только посмотреть, есть ли выбросы.

Здесь вы можете попрактиковаться в работе с нулями. Мета-вопрос на собеседовании, где вам придется заменить NULL нулями.

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

Выбросы могут возникать по разным причинам, например:

  • Ошибки измерения или ввода
  • Повреждение данных
  • Истинные статистические аномалии

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

Некоторыми часто используемыми методами обнаружения выбросов являются Z-показатель, IQR (межквартильный размах), ящичковые диаграммы, диаграммы рассеяния и методы визуализации данных. В некоторых запущенных случаях также используются методы машинного обучения.

Визуализация данных может помочь выявить выбросы. Для этого удобен коробочный сюжет Сиборна.

plt.figure(figsize=(10, 6))
sns.boxplot(data=df[['advertised_price', 'sale_price']])

Мы используем plt.figure(), чтобы установить ширину и высоту фигуры в дюймах.

Затем мы создаем коробчатую диаграмму для столбцов Advertised_price и sale_price, которая выглядит следующим образом.

 

Освоение искусства очистки данных в Python
 

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

plt.xlabel('Prices')
plt.ylabel('USD')
plt.ticklabel_format(style='plain', axis='y')
formatter = ticker.FuncFormatter(lambda x, p: format(x, ',.2f'))
plt.gca().yaxis.set_major_formatter(formatter)

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

Затем мы создаем форматтер, который будет отображать значения по оси Y с запятыми в виде разделителей тысяч и десятичных точек. Последняя строка кода применяет это к оси.

Теперь вывод выглядит так.

 

Освоение искусства очистки данных в Python
 

Теперь, как нам идентифицировать и удалить выброс?

Одним из способов является использование метода IQR.

IQR, или межквартильный размах, — это статистический метод, используемый для измерения изменчивости путем разделения набора данных на квартили. Квартили делят ранговый набор данных на четыре равные части, а значения в диапазоне первого квартиля (25-й процентиль) и третьего квартиля (75-й процентиль) составляют межквартильный диапазон.

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

  1. Сначала вычислите первый квартиль (Q1), третий квартиль (Q3), а затем определите IQR. IQR рассчитывается как Q3 – Q1.
  2. Любое значение ниже Q1 – 1.5IQR или выше Q3 + 1.5IQR считается выбросом.

На нашей диаграмме прямоугольник фактически представляет IQR. Линия внутри рамки — это медиана (или второй квартиль). «Усы» коробчатой ​​диаграммы представляют собой диапазон в пределах 1.5*IQR от Q1 и Q3.

Любые точки данных за пределами этих «усов» можно считать выбросами. В нашем случае это стоимость 12,000,000 XNUMX XNUMX долларов. Если вы посмотрите на диаграмму, вы увидите, насколько четко это представлено, и это показывает, почему визуализация данных важна для обнаружения выбросов.

Теперь давайте удалим выбросы, используя метод IQR в коде Python. Сначала мы удалим рекламируемые выбросы цен.

Q1 = df['advertised_price'].quantile(0.25)
Q3 = df['advertised_price'].quantile(0.75)
IQR = Q3 - Q1
df = df[~((df['advertised_price'] (Q1 - 1.5 * IQR)) |(df['advertised_price'] > (Q3 + 1.5 * IQR)))]

Сначала мы вычисляем первый квартиль (или 25-й процентиль), используя квантиль() функция. Мы делаем то же самое для третьего квартиля или 75-го процентиля.

Они показывают значения, ниже которых опускаются 25% и 75% данных соответственно.

Затем вычисляем разницу между квартилями. Пока что все это просто перевод шагов IQR в код Python.

На последнем этапе мы удаляем выбросы. Другими словами, все данные меньше Q1 – 1.5*IQR или больше Q3 + 1.5*IQR.

Оператор «~» отменяет условие, поэтому у нас остаются только те данные, которые не являются выбросами.

Затем мы можем сделать то же самое с ценой продажи.

Q1 = df['sale_price'].quantile(0.25)
Q3 = df['sale_price'].quantile(0.75)
IQR = Q3 - Q1
df = df[~((df['sale_price'] (Q1 - 1.5 * IQR)) |(df['sale_price'] > (Q3 + 1.5 * IQR)))]

Конечно, вы можете сделать это более лаконично, используя для цикла.

for column in ['advertised_price', 'sale_price']: Q1 = df[column].quantile(0.25) Q3 = df[column].quantile(0.75) IQR = Q3 - Q1 df = df[~((df[column] (Q1 - 1.5 * IQR)) |(df[column] > (Q3 + 1.5 * IQR)))]

Цикл повторяет два столбца. Для каждого столбца он вычисляет IQR, а затем удаляет строки в DataFrame.

Обратите внимание, что эта операция выполняется последовательно: сначала для рекламируемой_цены, а затем для продажной_цены. В результате DataFrame изменяется на месте для каждого столбца, а строки могут быть удалены, поскольку они являются выбросами в любом столбце. Таким образом, эта операция может привести к меньшему количеству строк, чем если бы выбросы для Advertised_price и sale_price были удалены независимо, а результаты впоследствии были объединены.

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

plt.figure(figsize=(10, 6))
sns.boxplot(data=df[['advertised_price', 'sale_price']])
plt.xlabel('Prices')
plt.ylabel('USD')
plt.ticklabel_format(style='plain', axis='y')
formatter = ticker.FuncFormatter(lambda x, p: format(x, ',.2f'))
plt.gca().yaxis.set_major_formatter(formatter)

Вот результат.

 

Освоение искусства очистки данных в Python
 

Вы можете попрактиковаться в вычислении процентилей в Python, решив задачу Вопрос для интервью на Генеральной Ассамблее.

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

К счастью, богатая экосистема библиотек Python делает этот процесс более управляемым. Мы научились удалять ненужные строки и столбцы, переформатировать данные и бороться с пропущенными значениями и выбросами. Это обычные шаги, которые необходимо выполнить с большинством любых данных. Однако иногда вам также придется объединить две колонки в одну, проверить существующие данные, назначьте ему ярлыкиили избавиться от белых пространств.

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

Если вы не видите удовлетворения в этом результате и чистые данные не вызывают у вас странного волнения, что же вы делаете в науке о данных!?
 

Нейт Росиди специалист по данным и продуктовой стратегии. Он также является адъюнкт-профессором, преподающим аналитику, и является основателем СтратаСкретч, платформа, помогающая специалистам по обработке данных подготовиться к интервью с реальными вопросами интервью от ведущих компаний. Свяжись с ним в Твиттер: StrataScratch or LinkedIn.

Отметка времени:

Больше от КДнаггетс