Работа с отсутствующими значениями в Python

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

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

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

Есть много способов справиться с недостающими значениями. Рассмотрим типичные варианты на примере набора данных - 'Titanic'. Эти данные являются открытым набором данных Kaggle.

Для анализа необходимо импортировать библиотеки Python и загрузить данные.

Для загрузки используется метод Pandas read.csv(). В скобках указывается путь к файлу в кавычках, чтобы Pandas считывал файл во фрейм данных (Dataframes - df) с этого адреса. Путь к файлу может быть URL адрес или вашим локальным адресом файла.

# import the libraries
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

# import the dataset
train_df = pd.read_csv(r'C:\Users\Tatiana\Desktop\Python\titanic\train.csv')
train_df.head(2)
Показывает первые 2 строки загруженного фрейма данных
Показывает первые 2 строки загруженного фрейма данных

Посмотрим на размер данных (количество строк, колонок):

train_df.shape

(891, 12)

Для просмотра статистической сводки каждого столбца, чтобы узнать распределение данных в каждом столбце используется метод describe( ). Этот метод показывает нам количество строк в столбце - count, среднее значение столбца - mean, столбец стандартное отклонение - std, минимальные (min) и максимальные (max) значения, а также границу каждого квартиля - 25%, 50% и 75%. Любые значения NaN автоматически пропускаются.

train_df.describe()
метод describe( )
метод describe( )

По умолчанию, метод describe( ) пропускает строки и столбцы не содержащие чисел - категориальные признаки. Чтобы включить сводку по всем столбцам нужно в скобках добавить аргумент - include = "all".

# describe all the columns
train_df.describe(include = "all")
метод describe(include = "all")
метод describe(include = "all")

Для категориальных признаков этот метод показывает: - Сколько уникальных значений в наборе данных - unique; top значения; частота появления значений - freg.

Метод info( ) - показывает информацию о наборе данных, индекс, столбцы и тип данных, ненулевые значения и использование памяти.

# look at the info
print(train_df.info())
показывает информацию о наборе данных, индекс, столбцы и тип данных, ненулевые значения и использование памяти.
показывает информацию о наборе данных, индекс, столбцы и тип данных, ненулевые значения и использование памяти.

В результате мы видим, что все колонки, кроме колонок 'Age', 'Cabin' и 'Embarked', содержат по 891 строк.

Колонка 'Survived' - это целевое значение. Показывает, кто выжил, а кто - нет. Эта колонка заполнена бинарными значениями:

0 - не выжил

1 - выжил

Метод - value_counts(). Подсчет значений - это хороший способ понять, сколько единиц каждой характеристики / переменной у нас есть.

train_df['Survived'].value_counts()
подсчет значений в колонке 'Survived'
подсчет значений в колонке 'Survived'

Из 891 пассажира выжило 342.

sns.set_style('whitegrid')
sns.countplot(x='Survived',data=train_df,palette='RdBu_r')
график выживаемости пассажиров
график выживаемости пассажиров

Теперь посмотрим на колонки которые имеют пропущенные значения.

Есть два метода обнаружения недостающих данных: - isnull() и notnull().

Результатом является логическое значение, указывающее, действительно ли значение, переданное в аргумент, отсутствует. «Истина» ( True ) означает, что значение является отсутствующим значением, а «Ложь» ( False ) означает, что значение не является отсутствующим.

# Evaluating for Missing Data
missing_data = train_df.isnull()
missing_data.head(6)
True - пропущенные значения
True - пропущенные значения

Используя цикл for в Python, мы можем быстро определить количество пропущенных значений в каждом столбце. Как упоминалось выше, «Истина» представляет отсутствующее значение, а «Ложь» означает, что значение присутствует в наборе данных. В теле цикла for метод ".value_counts ()" подсчитывает количество значений "True".

# Count missing values in each column
for column in missing_data.columns.values.tolist():
    print(column)
    print(missing_data[column].value_counts())
    print(" ")
количество пропущенных значений в каждом столбце.
количество пропущенных значений в каждом столбце.
количество пропущенных значений в каждом столбце.
количество пропущенных значений в каждом столбце.

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

train_df.isnull().sum()
количество пропущенных значений в каждом столбце.
количество пропущенных значений в каждом столбце.

'Age'

В колонке возраст - 'Age' не указано 177 значений. И нужно понять - это систематическая ошибка или какая-то случайная погрешность.

Н-р, может у пассажиров 1 класса (или у женщин) не спрашивали про возраст ( т. к. это было не прилично), или случайно пропустили. Понимание о причине пропущенных значений, определит - как работать с этими отсутствующими данными.

Нужно сгруппировать возраст, относительно того, отсутствует возраст или нет. Для группировки используем метод groupby().

True - отсутствует возраст

False - значение заполнено

# missing age or not
train_df.groupby(train_df['Age'].isnull()).mean()
метод groupby().  True - отсутствует возраст, False - значение заполнено
метод groupby(). True - отсутствует возраст, False - значение заполнено

В колонке Survived (выжившие и не выжившие) - True = 0.29. Это значит, что пассажиры у которых возраст отсутствовал имели меньше шансов выжить. У них также был более дешевый билет и более низкий класс. Следовательно делаем вывод, что возраст случайно не занесли.

Решение: Пропущенные значения заполнить средним значением.

# missing values are replaced by the average value
train_df['Age'].fillna(train_df['Age'].mean(), inplace = True)

sns.set_style('whitegrid')
%matplotlib inline

g = sns.FacetGrid(train_df, col='Survived')
g.map(plt.hist, 'Age', bins=10)
график выживаемости пассажиров в зависимости от возраста
график выживаемости пассажиров в зависимости от возраста

Посмотрим на график выживаемости пассажиров в зависимости от класса и возраста

# Survived passengers by Pclass and Age
grid = sns.FacetGrid(train_df, col ='Survived', row ='Pclass', height = 3.5, aspect=1.5)
grid.map(plt.hist, 'Age', alpha=.5, bins=10)
grid.add_legend();
график выживаемости пассажиров в зависимости от класса и возраста
график выживаемости пассажиров в зависимости от класса и возраста

'Cabin'

В колонке каюта ( 'Cabin') не указано 687 значений. Т. к. пропущенных значений много, можно удалить полностью колонку 'Cabin', а можно и оставить отсутствующие данные как - отсутствующие данные. Здесь важно понять: - Существует ли какая-то систематическая взаимосвязь между выживанием и тем, была ли у пассажира отдельная каюта.Для группировки используем метод groupby().

True - отсутствует упоминание о каюте

False - значение заполнено

#  missing cabin or not
# Relationship between the presence of a value in the "Cabin" column on the survival rate
train_df.groupby(train_df['Cabin'].isnull()).mean()
метод groupby(). True - отсутствует упоминание о каюте, False - значение заполнено
метод groupby(). True - отсутствует упоминание о каюте, False - значение заполнено

Те, пассажиры у кого запись отсутствует - выжили около 30%. А у кого запись о наличии каюты есть - выжило 67%.

Вывод: Есть взаимосвязь между выживанием и наличием каюты.

Решение:

Создать новую колонку 'Cabin_available' (бинарный классификатор).Используем метод where(), где прописываем условие: - Если значение в колонке 'Cabin' отсутствует, то присваиваем в колонке 'Cabin_available' - значение 0, если присутствует, то 1.

# Let's create a new column 'Cabin_available'
# If there is no value in the "Cabin" column, then = 0 and yes value = 1
train_df['Cabin_available'] = np.where(train_df['Cabin'].isnull(), 0,1)
train_df.head(6)
показывает первые 6 строк фрейма данных с новой колонкой 'Cabin_available'
показывает первые 6 строк фрейма данных с новой колонкой 'Cabin_available'

Выживаемость пассажиров в зависимости от наличия записи о каюте:

train_df.groupby(['Cabin_available']) ['Survived'].value_counts(normalize=True)
Выживаемость пассажиров в зависимости от наличия записи о каюте
Выживаемость пассажиров в зависимости от наличия записи о каюте
train_df.pivot_table(
  'PassengerId', 'Cabin_available', 'Survived', 'count').plot(
  kind='bar', stacked=True)
График выживаемости пассажиров в зависимости от наличия записи о каюте
График выживаемости пассажиров в зависимости от наличия записи о каюте

Теперь колонку 'Cabin' можно удалить.

train_df.drop(['Cabin'], axis = 1, inplace = True)
train_df
фрейм данных без колонки 'Cabin'
фрейм данных без колонки 'Cabin'

'Embarked'

В колонке порт посадки на борт ('Embarked') не указано два значения. Это категориальный признак.

Решение: Заменить пропущенные значения по частоте. Заменить отсутствующее значение значением, которым чаще всего встречается в конкретном столбце.

train_df['Embarked'].value_counts()
подсчет значений в колонке 'Embarked'
подсчет значений в колонке 'Embarked'

Чаще всего встречается значение S - 644. Нужно заменить пропущенные значения на S.

# replace the missing 'Embarked' values by the most frequent - S
train_df['Embarked'].replace(np.nan, 'S', inplace = True)
train_df['Embarked'].describe()
метод describe() для колонки 'Embarked', после замены пропущенных значений.
метод describe() для колонки 'Embarked', после замены пропущенных значений.

Good! Now, we have a dataset with no missing values. (Хорошо! Теперь у нас есть набор данных без пропущенных значений.)

train_df.isnull().sum()
набор данных без пропущенных значений
набор данных без пропущенных значений

Источник: https://habr.com/ru/post/663414/


Интересные статьи

Интересные статьи

Всем привет, При работе в IDA мне, да и, наверняка, вам тоже, часто приходится иметь дело с приложениями, которые имеют достаточно большой объём кода, не имеют символьной информаци...
Я часто повторяю, что .NET Core — это опенсорс и он работает «везде». MonoGame, Unity, Apple Watch, Raspberry Pi и микроконтроллеры, дюжина линуксов, Windows и так далее. Уже немало. Но кому-т...
Успех «Нетфликса» обеспечили высокие технологии, но за ними стоит целая философия, которая сделала эту философию эффективной. Систему, которая заставляет миллионы людей одержимо кликать по красно...
Вы когда-нибудь задумывались, как браузеры читают и исполняют JavaScript-код? Это выглядит таинственно, но в этом посте вы можете получить представление, что же происходит под капотом. Начнё...
Как обновить ядро 1С-Битрикс без единой секунды простоя и с гарантией работоспособности платформы? Если вы не можете закрыть сайт на техобслуживание, и не хотите экстренно разворачивать сайт из бэкапа...