EDA of dataset Python

в 11:19, , рубрики: анализ, анализ данных, Анализ и проектирование систем, анализ кода, анализ сложности алгоритмов, анализ трафика

Привет!

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

Очищать грязные данные можно c PandasРассмотрим основные методы.

Пропущенные значения

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

isnull() в Pandas возвращает DataFrame или Series с булевыми значениями, где True указывает на пропущенное значение. Аналогично, notnull() возвращает True для элементов, где значение присутствует:

Для начала объединим два датафрейма в единый, если нам это необходимо:

df = pd.concat([df1, df2], axis=0)

#d
pd.set_option('display.max_columns', None)
df.isnull().sum()
df['Ключевые навыки'] = df['Ключевые навыки'].fillna('Не указано')
df['Название вакансии'] = df['Название вакансии'].str.lower()#s
def edit_date(date):
 old_date = date.split()
 new_date = old_date[0]
 return new_dates
df['Дата публикации'] = df['Дата публикации'].apply(edit_date)
df.to_csv('vacancies_a.csv', index=False)
df.to_excel('vacancies_a.xlsx', index=False)
# удаляем строки, где есть хотя бы одно пропущенное значение
cleaned_df = df.dropna()# заполняем все пропущенные значения нулями
filled_df = df.fillna(0)
print("Очищенный DaaFrame:n", cleaned_df)
print("DataFrame с заполненными пропусками:n", filled_df)
# удаляем строки, где есть хотя бы одно пропущенное значение
cleaned_df = df.dropna()# заполняем все пропущенные значения нулями
filled_df = df.fillna(0)print("Очищенный DataFrame:n", cleaned_df)prit("DataFrame с заполненными пропусками:n", filled_df)

Код выведет таблицу, где True обозначает пропущенные значения.

- Что с ними делать дальше? Один из подходов – удаление строк или столбцов с пропусками, но это может привести к потере какой-то информации. Другой подход – заполнение пропусков.

Для заполнения пропусков используем метод fillna():

# заполняем пропуски средним значением по столбцам
df.fillna(df.mean(), inplace=True)
print("df с заполненными пропусками средним:n", df)

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

# заполнение пропусков в зависимости от условий
df['A'].fillna(value=df['A'].mean(), inplace=True)
df['B'].fillna(value=df['B'].median(), inplace=True)
# кастомная функция для заполненияdef custom_fill(series):    return series.fillna(series.mean())df.apply(custom_fill)

Удаление с помощью dropna()

По умолчанию dropna() удаляет строки, которые содержат хотя бы одно пропущенное значение:

import pandas as pd
import numpy as np
df = pd.DataFrame({    'Name': ['ivan', 'artem', np.nan, 'diana', 'eva'],    'Age': [25, np.nan, np.nan, 27, 28],    'City': ['New York', 'Los Angeles', 'Chicago', np.nan, 'Miami']})
# удаляем строки с пропущенными значениями
df_cleaned = df.dropna()print(df_cleaned)

dropna() удаляет все строки, где есть хотя бы одно NaN.

Чтобы удалить столбцы, содержащие пропущенные значения можно юзать параметр axis=1:

df_cleaned_columns = df.dropna(axis=1)
print(df_cleaned_columns)
# добавляем строку, полностью состоящую из NaN
df.loc[5] = [np.nan, np.nan, np.nan]# удаляем строки, где все значения являются NaN
df_cleaned_all = df.dropna(how='all')
print(df_cleaned_all)

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

# удаляем строки, где пропущены значения в определенных столбцах
df_cleaned_subset = df.dropna(subset=['Name', 'City'])
print(df_cleaned_subset)

В этом случае будут удалены только те строки, в которых отсутствуют значения в столбцах Name или City

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

# удаляем строки, где менее двух непропущенных значений
df_cleaned_thresh = df.dropna(thresh=2)
print(df_cleaned_thresh)

Кастомные варианты

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

Ср. значение:

import pandas as pd
import numpy as np
df = pd.DataFrame({    'A': [1, 2, np.nan, 4, 5],    'B': [np.nan, 2, 3, np.nan, 5],    'C': [1, 2, 3, 4, np.nan]})
# заполняем пропущенные значения в столбце A средним значением по этому столбцу
df['A'].fillna(df['A'].mean(), inplace=True)

Медиана

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

# фулим пропущенные значения в столбце B медианой
df['B'].fillna(df['B'].median(), inplace=True)

Мода

Для категориальных данных или данных с дискретными значениями можно использовать моду:

# C - категориальный столбец, заполняем пропущенные значения модой
df['C'].fillna(df['C'].mode()[0], inplace=True)

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

# Заполняем пропущенные значения в столбце A, используя кастомную логику
df['A'].fillna(df.apply(lambda row: row['B'] if pd.isnull(row['A']) else row['A'], axis=1), inplace=True)

Когда заполнение должно учитывать группировку по какому-либо признаку, можно использовать apply() или transform() совместно с groupby():

# допустим, есть столбец группы, и мы хотим заполнить пропуски средним значением внутри каждой группы
df['group'] = ['X', 'X', 'Y', 'Y', 'Z']
df['A'] = df.groupby('group')['A'].transform(lambda x: x.fillna(x.mean()))

А что насчет дубликатов?

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

drop_duplicates() позволяет не только удалять полные дубликаты строк, но и предоставляет настройки для работы с частичными дубликатами, удалим полные дупликаты:

import pandas as pd
df = pd.DataFrame({    'A': [1, 2, 2, 3, 3, 3],    'B': ['a', 'b', 'b', 'c', 'c', 'c'],    'C': [100, 200, 200, 300, 300, 300]})
# удаляем дубликаты
df_unique = df.drop_duplicates()
print(df_unique)

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

Часто нужно удалять дубликаты, основываясь не на всех столбцах, а только на некоторых. Для этого в drop_duplicates() есть параметр subset:

# удаляем дубликаты, основываясь только на столбцах 'A' и 'B'
df_unique_subset = df.drop_duplicates(subset=['A', 'B'])
print(df_unique_subset)

keep позволяет контролировать, какие дубликаты будут удалены: первый, последний или все:

# Удаляем все дубликаты, кроме последнего вхождения
df_keep_last = df.drop_duplicates(keep='last')
print(df_keep_last)

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

# преобразуем все строки в нижний регистр и удаляем пробелы
df['B'] = df['B'].str.lower().str.replace(' ', '')# теперь удаляем дубликаты
df_preprocessed = df.drop_duplicates()
print(df_preprocessed)

Категориальные данные

get_dummies() используется для преобразования категориальных переменных в фиктивные/индикаторные переменные, кстати в ml юзается довольно часто:

import pandas as pd
df = pd.DataFrame({    'Color': ['Red', 'Green', 'Blue', 'Green']})# преобразуем категориальные данные в индикаторные переменные
dummies = pd.get_dummies(df['Color'])
print(dummies)

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

factorize() используется для получения числового представления категориальных данных, присваивая каждой уникальной категории целочисленный идентификатор:

# получаем числовое представление категориальных данных
codes, uniques = pd.factorize(df['Color'])
print(codes)  # массив кодовprint(uniques)  # массив уникальных значений

str-методы позволяют выполнять такие операции, как преобразование регистра, поиск и замена подстрок, разбиение строк и т.п:

df_text = pd.DataFrame({    'Text': ['This is a test.', 'Hello, World!', 'Otus!']})# преобразуем все тексты в нижний регистр
df_text['Text_lower'] = df_text['Text'].str.lower()# удаляем знаки пунктуации
df_text['Text_clean'] = df_text['Text'].str.replace('[^ws]', '', regex=True)
print(df_text)

Иногда можно использовать str.replace(), str.findall().

Преобразование текстовых данных в числовые часто требуется для аналитических и ml моделей. Например, после использования factorize() для категориальных данных можно обратно преобразовать числовые коды в текстовые категории, используя массив uniques:

# преобразование кодов обратно в текстовые категории
df['Color_restored'] = codes
df['Color_restored'] = df['Color_restored'].map(lambda x: uniques[x])print(df)

Автор: Ksdfergo3

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js