В современном мире большинство бизнес-процессов связаны с обработкой больших объемов данных, получаемых от различных источников. Часто эти данные содержат ошибки, дубликаты и пропуски, что может привести к неверным выводам и решениям. Одним из инструментов, которые позволяют очистить и преобразовать данные, является библиотека pandas для языка программирования Python.
Я собираюсь рассмотреть задачу по очистке данных с помощью pandas. Для этого возьмем данные, содержащие дубликаты строк, неправильные типы данных, пропуски и отрицательные значения. Затем я буду использовать функциональные возможности pandas для очистки и преобразования этих данных в форму, пригодную для дальнейшего анализа.
Предположим, у вас есть набор данных, содержащий информацию о продажах компании за последние несколько лет. Но данные не очень чистые, и вы заметили, что есть некоторые проблемы с форматированием и некоторые строки содержат ошибки.
Задача: Необходимо очистить данные о продажах компании за последние несколько лет с помощью библиотеки Pandas.
Исходные данные:
Файл CSV, содержащий информацию о продажах компании за последние несколько лет.
Файл содержит следующие столбцы: дата продажи, название продукта, количество проданного товара, цена за единицу, общая стоимость продажи, имя продавца и регион продажи.
В некоторых строках присутствуют ошибки, например, неправильный формат даты или отсутствие цены за единицу.
Задачи, которые необходимо выполнить:
Загрузить исходные данные из файла в Pandas DataFrame.
Удалить строки, которые содержат ошибки в данных.
Привести столбец с датами к формату
datetime
.Привести столбцы с числами к числовому формату (float или int).
Определить и удалить дубликаты строк.
Сохранить очищенные данные в новый файл CSV.
Описание столбцов:
date
- дата продажи, в формате "YYYY-MM-DD";product_name
- название продуктаquantity
- количество продуктаunit_price
- цена за единицу продуктаtotal_price
- общая стоимость продукта, равная произведению количества и цены за единицуseller_name
- имя продавцаregion
- регион продажи
Загрузка данных
Чтобы загрузить данные в pandas, можно использовать метод read_csv()
для загрузки данных из файла CSV
или read_excel()
для загрузки данных из файла Excel
. В нашем случае у нас csv
файл.
Импортируем необходимые библиотеки и загружаем данные.
import pandas as pd
import re
df = pd.read_csv('data_with_errors.csv')
Выводим наш DataFrame.
df.head(5)
![](https://habrastorage.org/getpro/habr/upload_files/8e6/d2c/a2c/8e6d2ca2c7dbad0fe0dc21904af2773f.png)
На первый взгляд в данных видно наличие отрицательных значений и пропусков. Однако, в нашем задании сказано, что после загрузки мы должны удалить строки, в которых есть ошибки. Мы поступим немного по-другому. Сначала мы проверим типы столбцов, и если обнаружится, что какие-то столбцы не соответствуют данным, которые в них находятся, мы изменим тип на соответствующий. При возникновении проблем в ходе выполнения этой задачи, мы будем исправлять то, что будет необходимо.
Обработка данных
Для начала посмотрим на то, какие типы имеют наши столбцы. Для этого нам поможет команда info()
.
df.info()
Мы получаем информацию о нашем DataFrame, которая говорит нам о наличии пропусков в столбце total_price
. Также мы видим, что столбец с датами имеет строковый тип, также как и столбцы quantity
и unit_price
, которые содержат числовые данные. Нам необходимо это исправить.
![](https://habrastorage.org/getpro/habr/upload_files/3de/ded/e57/3dedede570029b9de00fcc38a5e5d7b9.png)
Попробуем сразу привести столбец date к типу datetime
. Для этого нам понадобится следующий код:
df['date'] = pd.to_datetime(df['date'], format='%Y-%m-%d')
К сожалению, этот код не сработает, так как в столбце с данными присутствуют значения, которые не позволяют сразу привести столбец к нужному нам типу. В результате работы выражения будет выведено сообщение об ошибке.
![](https://habrastorage.org/getpro/habr/upload_files/5d4/9ad/f96/5d49adf9628eaa43c6e4ee09dee3b22f.png)
Существует множество способов решения данной проблемы, один из них представлен ниже. Так как даты в нашем столбце date указаны в формате "YYYY-MM-DD", мы можем использовать регулярное выражение для поиска всех значений столбца, которые не соответствуют данному формату. Для этого мы создадим лямбда-функцию, которая будет применена к столбцу методом map()
. Регулярное выражение будет выглядеть следующим образом: `\d{4}-\d{2}-\d{2}`.
Создаем лямбда-функцию.
search = lambda x: x if re.search(r"\d{4}-\d{2}-\d{2}", x) else 'not found'
Применяем лямбда-функцию к столбцу date
.
df['date'] = df['date'].map(search)
Проверим результат.
df.query('date == "not found"').count()
Мы видим, что в 53 строках данные не соответствуют формату..
![](https://habrastorage.org/getpro/habr/upload_files/9f6/a36/4b7/9f6a364b7df13079de42ae41615bc5a6.png)
Посмотрим на эти строки, чтобы понять, с чем мы имеем дело.
df.query('date == "not found"').head(5)
![](https://habrastorage.org/getpro/habr/upload_files/2af/485/331/2af4853313bc14eb38b0e07f2595c843.png)
Мы замечаем отсутствие даты, а также латинские буквы вместо чисел в столбце количества quantity
. Кроме того, столбец total_price
содержит множество пропусков, а unit_price
имеет много повторяющихся значений. В таком виде данные не представляют ценности для анализа, и мы должны удалить строки, содержащие ошибки, как указано в задании.
df = df.drop(df.query('date == "not found"').index)
df.query('date == "not found"').count()
![](https://habrastorage.org/getpro/habr/upload_files/730/37e/920/73037e9206d3dd62118df9f6b9764df8.png)
Приведем столбец date
к нужному нам типу данных.
df['date'] = pd.to_datetime(df['date'], format='%Y-%m-%d')
df.info()
Видим что столбец date
теперь имеет тип datetime.
![](https://habrastorage.org/getpro/habr/upload_files/17d/9d1/06f/17d9d106f110696e7ecab3c2c4f547e7.png)
Для того чтобы привести столбец quantity
к числовому формату, мы можем использовать метод to_numeric()
с параметром errors='coerce'
, который преобразует значения в числа, а нечисловые значения заменяет на NaN.
df['quantity'] = pd.to_numeric(df['quantity'], errors='coerce')
Тоже самое мы делаем с unit_price.
df['unit_price'] = pd.to_numeric(df['unit_price'], errors='coerce')
Для продолжения, мы сфокусируемся на отрицательных значениях в указанных столбцах и выведем их на экран.
df.query('quantity < 0')
![](https://habrastorage.org/getpro/habr/upload_files/afd/ee3/b73/afdee3b73da4715668c4184fd1a54461.png)
Эти значения будут преобразованы с помощью функции abc()
, чтобы преобразовать отрицательные значения в столбцах. Это позволит получить абсолютные значения и избавиться от знака минус.
df.loc[df['quantity'] < 0,'quantity'] = abs(df['quantity'])
Таким же образом мы поступим unit_price.
df.query('unit_price < 0')
![](https://habrastorage.org/getpro/habr/upload_files/0e9/352/621/0e9352621c8ac8b365e8cf4ee8ad17c6.png)
Заменяем отрицательные значения на положительные.
df.loc[df['unit_price'] < 0,'unit_price'] = abs(df['unit_price'])
Обработаем столбец total_price
. В задаче указано, что total_price
представляет собой общую стоимость продукта, которая равна произведению количества и цены за единицу. Значит, мы можем заполнить пустые значения в этом столбце, умножив значение quantity
на значение unit_price
. Так и поступим.
df.loc[df['total_price'].isna(), 'total_price'] = df['quantity'] * df['unit_price']
Данные содержат некоторое количество дубликатов, которые необходимо удалить в соответствии с заданием.
df[df.duplicated()]
![](https://habrastorage.org/getpro/habr/upload_files/921/3a0/c45/9213a0c458e44c068aca233c20b7a25a.png)
Удаляем дубликаты.
df = df.drop(df[df.duplicated()].index)
Проверим категориальные переменные.
df.product_name.unique()
![](https://habrastorage.org/getpro/habr/upload_files/85b/a95/41c/85ba9541c155c410e19a75c7ccb4d48e.png)
df.seller_name.unique()
![](https://habrastorage.org/getpro/habr/upload_files/49b/5b4/61e/49b5b461e8466c6a166b4cfa7a4f186d.png)
df.region.unique()
![](https://habrastorage.org/getpro/habr/upload_files/265/055/89c/26505589ca884459de4be389d17c0989.png)
Все значения категориальных переменных в порядке. Осталось только сохранить данные в csv. В этом нам поможет функция to_csv()
.
df.to_csv('processed_data.csv',index=False, header=True)
В результате мы получим файл processed_data.csv
.
Заключение
Такое задание позволяет закрепить навыки работы с pandas, например, загрузка данных из файла, очистка данных от дубликатов и пропусков, изменение типов данных столбцов и обработка пропущенных значений. Задание также поможет новичкам овладеть принципами анализа данных, включая методы pandas для анализа данных.
В скором времени я планирую выложить разбор реальной задачи для продуктового аналитика, который поможет вам лучше понять, как применять знания и навыки, полученные в процессе изучения данной темы. Я надеюсь, что этот материал будет интересен и полезен для вас, и вы сможете успешно применить полученные знания на практике. Буду благодарен за ваши комментарии! Спасибо!