Время прочтения: 6 мин.

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

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

  • типы данных;
  • вызов библиотек;
  • конструктор для таблиц DataFrame;
  • срезы данных.

Исходные данные:

На входе у нас есть Data Frame с данными о поле (м или ж), возрасте, контактной информацией, а также признаком. Для тех, кто не любит абстрагироваться, признак – это ответ на вопрос «Играете ли вы в компьютерные игры?» и он может принимать одно из двух значений (да или нет).

Шаг 1. Знакомство с данными

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

Выведем первые строки методом head():

df.head()

Результат:

Посмотрим сводную информацию методом info():

df.info()

Результат:

Метод info() дает много информации, из которой мы узнаем, что в таблице 20 строк, 4 столбца, видим типы данных для каждого столбца и количество ненулевых значений.

Шаг 2. Переименование столбцов

Является необязательным шагом, но он делает дальнейшие действия более удобными, а внешний вид приятным. Обычной рекомендацией для названия столбцов является: применение латиницы в названии, нижний регистр, а также отсутствие пропусков в имени столбца (заменяется на символ «_»). Для переименования столбцов применим метод set_axis():

col_name = ['tag', 'gender', 'age', 'phone_num']
df.set_axis(col_name, axis = 'columns', inplace = True)

Результат:

Шаг 3. Пропуски данных

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

  • dropna() – удаление строк, где есть пропущенные значения.
  • dropna(subset=[‘col1’, ‘col2’], inplace=True) – удаление строк, где есть пропущенные значения в определенных столбцах (subset).
  • dropna(axis=’col1′, inplace=True) – для удаления столбцов с пропущенными значениями.

В зависимости от данных и решаемой задачи пропущенные значения могут быть заменены на характерные значения: среднее арифметическое или медиана. Также стоит отметить, что пропущенные значения могут «маскироваться» (например под None), для определения этого, можно сначала выполнить поиск уникальных значений методом unique().

Удалим все строки, в которых пропущено значение в столбце ‘tag’ методом dropna():

df.dropna(subset = ['tag'], inplace=True)

Заменим пропущенный возраст ‘age’, на средний возраст, характерный для определенного пола с определенным признаком, но перед этим проверим какие уникальные значения принимаются в данном столбце. Затем применим метод replace() к значениям ‘None’ и заменим их на NaN:

df.age.unique()

Результат:

df.age = df.age.replace('None', np.nan)

Выведем на экран срез данных с пропущенными значениями в столбце ‘age’ применив метод isnull():

df[df['age'].isnull() == True]

Результат:

Заменим пропущенные значения методом fillna() на средний возраст играющих в компьютерные игры мужчин (пропущенные значения соответствуют этим признакам):

mean_age = round(df[(df['tag'] == 'да') & (df['gender'] == 'м')]['age'].mean())
print(mean_age)

Результат:

df['age'] = df['age'].fillna(mean_age)

Шаг 4. Дубликаты

Для нахождения дубликатов применяется метод duplicated(), совместно с методом sum() можно определить количество дубликатов.

Для удаления дубликатов используем методом следующую конструкцию:

drop_duplicates().reset_index(drop=True)

Метод reset_index() необходим для изменения индексации, так как drop_duplicates() вместе со строками удаляет и их индексы.

Проверим наличие дубликатов:

df[df.duplicated() == True]

Результат:

df.duplicated().sum()

Результат:

Удалим дубликаты и проверим результат:

df = df.drop_duplicates().reset_index(drop=True)
df.duplicated().sum()

Результат:

Шаг 5. Изменение типов данных

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

df.head(2)

Результат:

df.dtypes

Результат:

Для того, чтобы они стали более «нарядными», нужно изменить тип данных в столбцах ‘age’ и ‘phone_num’ на int.

Для перевода значений формата string в числовой формат применяется метод библиотеки Pandas to_numeric(). От значения errors метода to_numeric(), зависят действия при работе с некорректным значением:

  • errors=’raise’ — выдается ошибка, операция прерывается;
  • errors=’coerce’ — некорректные значения заменяются на NaN;
  • errors=’ignore’ — некорректные значения игнорируются, но остаются.

Применим метод to_numeric() к столбцу ‘phone_num’:

df['phone_num'] = pd.to_numeric(df['phone_num'], errors='coerce')
df.dtypes

Результат:

Для того, чтобы перевести данные в нужный тип, применяется метод astype():

df['phone_num'] = df['phone_num'].astype('int64')

При вызове метода была получена ошибка:

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

df['phone_num'] = df['phone_num'].fillna(pd.NA)
df['phone_num'] = df['phone_num'].astype('Int64')
df['age'] = df['age'].astype('Int64')

Посмотрим на достигнутый результат:

df.info()

Результат:

df.head(2)

Результат:

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

Заключение

На этом пост подошел к концу, вспомним чему мы научились:

  • Знакомиться с общей информацией, находящейся в таблице.
  • Переименовывать столбцы.
  • Работать с пропусками.
  • Находить и удалять дубликаты.
  • Менять тип данных.