Очистка и подготовка данных в Pandas и Python
В этом руководстве вы научитесь очищать и подготавливать данные в Pandas DataFrame. Вы узнаете, как работать с пропущенными данными, дубликатами данных и неаккуратными строковыми данными. Умение эффективно очищать и готовить набор данных — важный навык. Многие специалисты по данным считают, что они тратят 80% своего времени на очистку и подготовку своих наборов данных.
Pandas предоставляет вам несколько быстрых, гибких и интуитивно понятных способов очистки и подготовки данных. К концу этого руководства вы узнаете всё, что нужно для начала работы с:
Работа с отсутствующими данными с использованием методов, таких как
.fillna()
Работа с повторяющимися данными с использованием методов, таких как метод
.remove_duplicates()
Очистка строковых данных с использованием аксессора
.str
Обработка отсутствующих данных в Pandas
Чтобы следовать этому разделу руководства, давайте загрузим неупорядоченный DataFrame с помощью Pandas, который мы можем использовать для изучения способов работы с отсутствующими данными. Если вы хотите следовать за каждым шагом, просто скопируйте код ниже, чтобы загрузить DataFrame:
# Загрузка образца DataFrame с использованием библиотеки Pandas
import pandas as pd
import numpy as np
df = pd.DataFrame.from_dict({
'Name': ['Nik', 'Kate', 'Evan', 'Kyra', np.NaN],
'Age': [33, 32, 40, 57, np.NaN],
'Location': ['Toronto', 'London', 'New York', np.NaN, np.NaN]
})
print(df)
# Вывод:
# Name Age Location
# 0 Nik 33.0 Toronto
# 1 Kate 32.0 London
# 2 Evan 40.0 New York
# 3 Kyra 57.0 NaN
# 4 NaN NaN NaN
При выводе DataFrame мы видим, что у нас есть три столбца. Каждый столбец содержит как минимум одно отсутствующее значение.
Понимание метода isnull в Pandas
Pandas предоставляет чрезвычайно полезный метод .isnull()
, который определяет, отсутствует ли значение. Метод возвращает логическое значение: True
или False
. Мы можем применить метод как ко всему DataFrame, так и к одному столбцу. Метод корректно распространяется на Series или DataFrame в зависимости от того, к чему он применяется. Давайте быстро рассмотрим:
# Исследуем метод .isnull()
print(df.isnull())
# Вывод:
# Name Age Location
# 0 False False False
# 1 False False False
# 2 False False False
# 3 False False True
# 4 True True True
После того как мы применили метод ко всему DataFrame, каждое значение было оценено на наличие или отсутствие данных. В следующих разделах вы узнаете, как использовать этот метод для преобразования вашего DataFrame.
Подсчет пропущенных значений в Pandas DataFrame
Первым шагом, который вы захотите предпринять, будет определить, сколько значений отсутствуют в вашем DataFrame. Один из способов сделать это — использовать цепочку методов .isnull()
и .sum()
# Выводим количество пропущенных значений в каждом столбце с помощью метода .isnull().sum()
print(df.isnull().sum())
# Вывод:
# Name 1
# Age 1
# Location 2
# dtype: int64
Причина, по которой это работает, заключается в том, что значение True
фактически представлено значением 1, а False
- значением 0. Благодаря этому мы можем применить метод .sum()
к DataFrame. Это возвращает Series, содержащий количество отсутствующих элементов в каждом столбце.
Как подсчитать непропущенные данные в Pandas DataFrame?
В Pandas есть функция отрицания .isnull()
. Чтобы посчитать данные, которые не отсутствуют в каждом столбце, можно объединить методы .notnull()
и .sum()
. Это возвращает Series с количеством ненулевых данных в каждом столбце.
Удаление отсутствующих данных в Pandas DataFrame
При работе с отсутствующими данными часто рекомендуется сделать одно из двух: либо удалить записи, либо найти способы заполнить данные. В этом разделе вы узнаете, как выполнить первое из двух действий. Pandas предоставляет метод .dropna()
, который используется для удаления отсутствующих данных. Давайте рассмотрим этот метод:
# Исследуем метод Pandas .dropna()
df.dropna(
axis=0, # Указываем, удалять ли строки или столбцы (0 - строки, 1 - столбцы)
how='any', # Указываем, удалять ли записи, если 'all' или 'any' из них пропущены
thresh=None, # Указывает минимальное количество необходимых заполненных значений для сохранения строки/столбца
subset=None, # Указываем, какие строки/столбцы учитывать при удалении
inplace=False # Указывает, удалять ли данные в месте (то есть без необходимости заново присваивать)
)
Давайте посмотрим, как некоторые из этих параметров могут быть использованы для изменения поведения метода. Сначала давайте просто применим метод со всеми стандартными аргументами и изучим результаты:
# Удаление пропущенных значений с использованием параметров по умолчанию
df = df.dropna()
print(df)
# Вывод результата после удаления пропущенных значений:
# Name Age Location
# 0 Nik 33.0 Toronto
# 1 Kate 32.0 London
# 2 Evan 40.0 New York
По умолчанию, Pandas удаляет записи, где отсутствует любое значение. Из-за этого также была удалена четвертая строка, в которой отсутствовало только одно значение.
Мы можем изменить это поведение, чтобы удалять запись только в том случае, если все записи отсутствуют. Посмотрим, как мы можем это сделать:
# Удаляем строки, если все значения в строке отсутствуют (равны NaN)
df = df.dropna(how='all')
print(df)
# Вывод:
# Name Age Location
# 0 Nik 33.0 Toronto
# 1 Kate 32.0 London
# 2 Evan 40.0 New York
# 3 Kyra 57.0 NaN
Аналогично, мы можем использовать следующие параметры для более точной настройки работы метода
thresh=
: количество элементов, которые должны быть пустымиsubset=
: названия столбцов, которые нужно учитывать при рассмотрении отсутствующих значений.
Заполнение отсутствующих данных в Pandas DataFrame
Удаление пропущенных данных также удаляет любые связанные данные из этих записей. Поэтому может быть полезно заполнить пропущенные значения. Вы можете сделать это, используя метод .fillna()
. Метод может быть применен как ко всему DataFrame, так и к одному столбцу. Заполнение константой в качестве параметра заменяет все пропущенные значения на это значение:
# Используем .fillna() для заполнения пропущенных значений нулями
df = df.fillna(0)
print(df)
# Вывод:
# Name Age Location
# 0 Nik 33.0 Toronto
# 1 Kate 32.0 London
# 2 Evan 40.0 New York
# 3 Kyra 57.0 0.0
# 4 0 0.0 0.0
При работе с различными типами данных не всегда целесообразно заполнять все пропущенные данные одним и тем же значением. Поэтому вы можете передать словарь для заполнения данных разными значениями. Ключи словаря представляют столбцы, а значения представляют значения для заполнения.
# Заполнение столбцов различными значениями
df = df.fillna({'Name': 'Someone', 'Age': 25, 'Location': 'USA'})
print(df)
# Вывод:
# Name Age Location
# 0 Nik 33.0 Toronto
# 1 Kate 32.0 London
# 2 Evan 40.0 New York
# 3 Kyra 57.0 USA
# 4 Someone 25.0 USA
Один из очень удобных способов справиться с отсутствующими значениями — это интерполировать их значения. Это означает заполнение отсутствующих значений оценочными. Простой пример: можно заполнить отсутствующие значения возраста средним возрастом, что можно сделать, используя среднее значение для этого столбца.
# Замена пропущенных значений в столбце 'Age' средним значением этого столбца
df['Age'] = df['Age'].fillna(df['Age'].mean())
print(df)
# Вывод:
# Name Age Location
# 0 Nik 33.0 Toronto
# 1 Kate 32.0 London
# 2 Evan 40.0 New York
# 3 Kyra 57.0 40.5
# 4 NaN 40.5 NaN
В следующем разделе вы узнаете, как справляться с дублированными данными в DataFrame Pandas.
Работа с дублирующимися данными в Pandas
Дублированные данные могут быть введены в набор данных по нескольким причинам. Иногда такие данные могут быть действительными, в то время как в других случаях они могут вызвать серьезные проблемы с целостностью ваших данных. Из-за этого важно понимать, как находить и обрабатывать дублированные данные. Давайте загрузим пример набора данных, который содержит разные типы дублированных данных:
# Загрузка образцового DataFrame из библиотеки Pandas
import pandas as pd
df = pd.DataFrame.from_dict({
'Name': ['Nik', 'Kate', 'Evan', 'Kyra', 'Nik', 'Kate'],
'Age': [33, 32, 40, 57, 33, 32],
'Location': ['Toronto', 'London', 'New York', 'Atlanta', 'Toronto', 'Paris'],
'Date Modified': ['2022-01-01', '2022-02-24', '2022-08-12', '2022-09-12', '2022-01-01', '2022-12-09']
})
print(df)
# Вывод:
# Name Age Location Date Modified
# 0 Nik 33 Toronto 2022-01-01
# 1 Kate 32 London 2022-02-24
# 2 Evan 40 New York 2022-08-12
# 3 Kyra 57 Atlanta 2022-09-12
# 4 Nik 33 Toronto 2022-01-01
# 5 Kate 32 Paris 2022-12-09
В загруженном вами DataFrame есть несколько записей, которые являются полностью уникальными, а другие частично или полностью дублируются. В следующем разделе вы узнаете, как выявить дублированные записи.
Выявление дубликатов записей в Pandas DataFrame
Pandas предоставляет полезный метод .duplicated()
, который позволяет выявлять дублирующиеся записи в наборе данных. Этот метод, аналогичный методу .isnull()
, возвращает булевые значения, когда существуют дубликаты записей. Метод возвращает единственную серию, если записи дублируются.
# Определение дублирующихся записей в DataFrame Pandas
print(df.duplicated())
# Вывод:
# 0 False
# 1 False
# 2 False
# 3 False
# 4 True
# 5 False
# dtype: bool
На первый взгляд это может показаться не особо полезным. Однако данный метод, как вы вскоре узнаете, позволяет нам удалять дублирующиеся записи. Более того, это позволяет нам подсчитывать количество дублирующихся записей. Например, мы можем просто сложить Series, чтобы определить, сколько дублирующихся записей существует.
# Подсчет количества дублирующихся записей в DataFrame
print(df.duplicated().sum())
# Вывод:
# 1
Это позволяет вам понять степень дублирующихся записей в наборе данных. Знание количества дубликатов может дать вам лучшее представление о возможных проблемах с целостностью данных.
Удаление дубликатов данных в Pandas DataFrame
Pandas упрощает удаление дублированных записей с помощью метода .drop_duplicates()
. Давайте рассмотрим параметры, которые доступны для этого метода:
# Метод Pandas .drop_duplicates() для удаления дублирующихся записей
df.drop_duplicates(
subset=None, # Какие столбцы учитывать при определении дубликатов
keep='first', # Оставлять ли первую встречу дубликата
inplace=False, # Удалять дублирующиеся записи непосредственно в исходном DataFrame
ignore_index=False # Пренебрегать индексацией после удаления дубликатов
)
Посмотрим, что произойдет, если применить метод со всеми параметрами по умолчанию:
# Удаление дублирующихся записей с использованием по умолчанию аргументов
df = df.drop_duplicates()
print(df)
# Вывод:
# Name Age Location Date Modified
# 0 Nik 33 Toronto 2022-01-01
# 1 Kate 32 London 2022-02-24
# 2 Evan 40 New York 2022-08-12
# 3 Kyra 57 Atlanta 2022-09-12
# 5 Kate 32 Paris 2022-12-09
Мы видим, что это вернуло DataFrame, где совпали только все элементы. Он сохранил первую запись нашего дубликата (индекс 0).
Теперь давайте посмотрим, как мы можем расширить функциональность этого метода. Мы видим, что у нас есть две довольно похожие записи: индексы 1 и 5. Также видно, что они дублируются только по двум столбцам, и одна из записей более новая.
Мы можем изменить поведение метода, чтобы сохранять самую последнюю запись, сначала отсортировав данные по дате последнего изменения. Затем мы можем попросить Pandas удалить записи, основываясь на подмножестве соответствующих столбцов. Давайте посмотрим, как:
# Удаление дублирующихся записей на основе подмножества столбцов
df = df.sort_values(by='Date Modified', ascending=False)
df = df.drop_duplicates(subset=['Name', 'Age'], keep='first')
print(df)
# Вывод:
# Name Age Location Date Modified
# 5 Kate 32 Paris 2022-12-09
# 3 Kyra 57 Atlanta 2022-09-12
# 2 Evan 40 New York 2022-08-12
# 0 Nik 33 Toronto 2022-01-01
Давайте разберем, что мы здесь сделали:
Мы отсортировали данные по
'Date Modified'
в порядке убывания. Это размещает более новые записи первыми.Затем мы удаляем дубликаты на основе
'Name'
и'Age'
, оставляя первый экземпляр.
В следующем разделе вы узнаете, как очищать строки в Pandas.
Очистка строк в Pandas
Одним из преимуществ работы с Pandas является его высокая способность работать с текстовыми данными. Это становится еще более мощным благодаря возможности доступа к любому типу строкового метода и применению его непосредственно ко всему массиву данных. В этом разделе вы научитесь удалять пробелы, разбивать строки на столбцы и заменять текст в строках.
Давайте загрузим DataFrame Pandas, который содержит строковые данные для работы.
# Загрузка образцового DataFrame из библиотеки Pandas
import pandas as pd
df = pd.DataFrame.from_dict({
'Name': ['Tranter, Melvyn', 'Lana, Courtney', 'Abel, Shakti', 'Vasu, Imogene', 'Aravind, Shelly'],
'Region': ['Region A', 'Region A', 'Region B', 'Region C', 'Region D'],
'Location': ['TORONTO', 'LONDON', 'New york', 'ATLANTA', 'toronto'],
'Favorite Color': [' green ', 'red', ' yellow', 'blue', 'purple ']
})
print(df)
# Вывод:
# Name Region Location Favorite Color
# 0 Tranter, Melvyn Region A TORONTO green
# 1 Lana, Courtney Region A LONDON red
# 2 Abel, Shakti Region B New york yellow
# 3 Vasu, Imogene Region C ATLANTA blue
# 4 Aravind, Shelly Region D toronto purple
Мы видим, что наша DataFrame содержит неупорядоченные строковые данные! Например, некоторые столбцы содержат несколько данных (имя и фамилия), другие имеют избыточные данные (слово «Region»), имеют неаккуратную капитализацию (местоположение) и добавленные пробелы (любимые цвета).
Чтобы применить строковые методы ко всему объекту Series в Pandas, нужно использовать атрибут .str
, который предоставляет доступ к векторизованным строковым методам.
Обрезка пробелов в строках Pandas
Давайте начнем с удаления пробелов из текста в Pandas. Мы видим, что столбец 'Favorite Color'
содержит лишние пробелы в начале и конце названия цвета. В Python есть несколько методов удаления пробелов из начала строки, конца строки или с обеих сторон. Поскольку пробелы находятся с обеих сторон строки, мы воспользуемся методом .strip()
.
# Удаление пробельных символов с обеих сторон из столбца DataFrame Pandas
df['Favorite Color'] = df['Favorite Color'].str.strip()
print(df)
# Вывод:
# Name Region Location Favorite Color
# 0 Tranter, Melvyn Region A TORONTO green
# 1 Lana, Courtney Region A LONDON red
# 2 Abel, Shakti Region B New york yellow
# 3 Vasu, Imogene Region C ATLANTA blue
# 4 Aravind, Shelly Region D toronto purple
Здесь мы смогли успешно удалить пробелы из столбца, повторно присвоив его самому себе.
Разделение строк на столбцы в Pandas
Столбец 'Имя'
содержит как фамилию, так и имя человека. Во многих случаях вам может понадобиться разделить этот столбец на два – отдельно для имени и фамилии. Этот подход будет работать немного иначе, так как нам нужно будет назначить два столбца, а не один.
Посмотрим, что произойдет, когда мы применим метод .str.split()
к столбцу:
# Применение метода .split на столбце DataFrame Pandas
print(df['Name'].str.split(','))
# Вывод:
# 0 [Tranter, Melvyn]
# 1 [Lana, Courtney]
# 2 [Abel, Shakti]
# 3 [Vasu, Imogene]
# 4 [Aravind, Shelly]
# Name: Name, dtype: object
Мы видим, что это вернуло список строк. Однако, чтобы назначить это нескольким столбцам, нам нужно передать аргумент expand=True
, чтобы указать Pandas разделить значения на отдельные элементы. После этого мы можем присвоить значения двум столбцам.
# Разделение столбца 'Name' на два новых столбца: 'Last Name' и 'First Name'
df[['Last Name', 'First Name']] = df['Name'].str.split(',', expand=True)
print(df)
# Вывод:
# Name Region Location Favorite Color Last Name First Name
# 0 Tranter, Melvyn Region A TORONTO green Tranter Melvyn
# 1 Lana, Courtney Region A LONDON red Lana Courtney
# 2 Abel, Shakti Region B New york yellow Abel Shakti
# 3 Vasu, Imogene Region C ATLANTA blue Vasu Imogene
# 4 Aravind, Shelly Region D toronto purple Aravind Shelly
Обратите внимание на использование двойных квадратных скобок. Это необходимо, так как мы передаем список колонок, которые хотим создать!
Замена текста в строках в Pandas
В столбце 'Region'
слово «Region» избыточно. В этом примере вы научитесь заменять текст в столбце. В частности, вы научитесь удалять заданную подстроку в более длинной строке. Для этого мы можем использовать метод .replace()
, который как раз подходит для такой задачи. Метод принимает строку, которую мы хотим заменить, и строку, на которую хотим заменить. Поскольку мы хотим удалить подстроку, мы просто передадим пустую строку в качестве замены.
# Замена подстроки в столбце DataFrame Pandas
df['Region'] = df['Region'].str.replace('Region ', '')
print(df)
# Вывод:
# Name Region Location Favorite Color
# 0 Tranter, Melvyn A TORONTO green
# 1 Lana, Courtney A LONDON red
# 2 Abel, Shakti B New york yellow
# 3 Vasu, Imogene C ATLANTA blue
# 4 Aravind, Shelly D toronto purple
Изменение регистра строк в Pandas
В этом разделе мы узнаем, как исправить странные и несоответствующие регистры, которые существуют в столбце 'Location'
. Pandas предоставляет доступ к ряду методов, позволяющих изменять регистр строк:
.upper()
преобразует строку в верхний регистр..lower()
преобразует строку в нижний регистр.title()
преобразует строку в формат заглавных букв
В этом случае мы хотим, чтобы наши местоположения были в виде заголовков, поэтому мы можем применить метод .str.title()
к строке:
# Преобразование текста в столбце DataFrame Pandas к формату заголовков (title case)
df['Location'] = df['Location'].str.title()
print(df)
# Вывод:
# Name Region Location Favorite Color
# 0 Tranter, Melvyn Region A Toronto green
# 1 Lana, Courtney Region A London red
# 2 Abel, Shakti Region B New York yellow
# 3 Vasu, Imogene Region C Atlanta blue
# 4 Aravind, Shelly Region D Toronto purple
Мы видим, что применяя метод .str.title()
, каждое слово было написано с заглавной буквы.
Упражнения
Пришло время проверить свои знания! Попробуйте решить упражнения ниже. Если вы хотите проверить свое решение, просто переключите поле, чтобы увидеть пример решения. Загрузите приведенный ниже DataFrame, чтобы ответить на вопросы:
# Загрузка DataFrame из библиотеки Pandas с использованием словаря данных
import pandas as pd
import numpy as np
df = pd.DataFrame.from_dict({
'Name': ['Tranter; Melvyn', 'Lana; Courtney', 'Abel; Shakti', 'Vasu; Imogene', 'Aravind; Shelly', 'Tranter; Melvyn'],
'Location': ['TORONTO', 'LONDON', 'New york', np.NaN, 'toronto', 'Madrid'],
'Sales': [123, 243, 654, np.NaN, 345, np.NaN]
})
print(df)
# Вывод:
# Name Location Sales
# 0 Tranter; Melvyn TORONTO 123.0
# 1 Lana; Courtney LONDON 243.0
# 2 Abel; Shakti New york 654.0
# 3 Vasu; Imogene NaN NaN
# 4 Aravind; Shelly toronto 345.0
# 5 Tranter; Melvyn Madrid NaN
Question 1
Question 2
Question 3
Создайте столбцы Имя и Фамилия. Обратите внимание, что имена разделены точкой с запятой.
df[['Last Name', 'First Name']] = df['Name'].str.split(';', expand=True)
Удалите все дублирующиеся записи, основываясь только на столбце "Name", сохраняя последнюю запись.
df = df.drop_duplicates(subset='Name', keep='last')
Рассчитать процент отсутствующих записей в каждом столбце.
Разделите результат df.isnull().sum()
на длину датафрей
print(df.isnull().sum() / len(df))
# Вывод:
# Name 0.000000
# Location 0.166667
# Sales 0.333333
# dtype: float64
Заключение и резюме
В этом руководстве вы узнали, как использовать Pandas для очистки данных! В следующем разделе приведен краткий обзор того, что вы узнали в этом руководстве:
Pandas предоставляет множество методов для манипуляции и очистки данных.
Пропущенные данные можно определить с помощью метода
.isnull()
. Количество пропущенных данных по каждому столбцу можно подсчитать, добавив метод.sum()
, который возвращает Series с количеством по каждому столбцу.Пропущенные данные можно удалить с помощью метода
.dropna()
, который можно настроить с использованием различных параметров.Повторяющиеся данные можно найти с помощью метода
.isduplicate()
Метод
.drop_duplicates()
может быть использован для удаления дублирующих записей, предлагая значительные возможности для настройки того, какие записи считать дубликатамиPandas может использовать строковые методы Python через атрибут
.str
. Это может быть полезно для применения векторизированных методов очистки к неструктурированным текстовым данным.
Дополнительные ресурсы
To learn more about related topics, check out the following tutorials:
Pandas Fillna – Работа с пропущенными значениями
Установить условный столбец Pandas на основе значений другого столбца
Last updated