201918

10 трюков библиотеки Python Pandas, которые вам нужны

Любите панд? Мы тоже. А еще мы любим эффективный код, поэтому собрали классные трюки, которые облегчат работу с библиотекой Python Pandas.

Некоторые команды уже знакомы? А вы не пробовали использовать их таким образом? ;)

read_csv

Все знают эту команду. Но когда данные, которые вы пытаетесь обработать, большие, попробуйте добавить аргумент nrows = 5, чтобы прочитать только крошечную часть таблицы перед фактической загрузкой всей таблицы. Зачем? Так удастся избежать ошибки с выбором неправильного разделителя, ведь это не всегда запятая.

Или используйте head в Linux, чтобы вывести первые, скажем, 5 строк из любого текстового файла: head –n 5 data.txt.

Извлеките список столбцов с df.columns.tolist(). Добавьте аргумент usecols = ['c1', 'c2',…], чтобы загрузить только необходимые столбцы. Кроме того, если знаете типы данных нескольких конкретных столбцов, добавьте аргумент dtype = {'c1': str, 'c2': int,…}. Так загрузка будет быстрее. Этот аргумент даёт ещё одно преимущество. Если один столбец содержит строки и числа, рекомендуется объявить его тип строковым. Так вы избежите ошибок при объединении таблиц, когда используете этот столбец как ключ.

select_dtypes

Если нужна предварительная обработка данных на языке Python, то эта команда сэкономит вам время. После чтения из таблицы типами данных по умолчанию для каждого столбца будут bool, int64, float64, object, category, timedelta64 или datetime64. Можете сначала проверить распределение с помощью

df.dtypes.value_counts()

чтобы узнать все типы данных объекта DataFrame. Далее выполните

df.select_dtypes(include = ['float64', 'int64'])

чтобы выбрать подмножество объекта DataFrame только с числовыми характеристиками.

copy

Это важная команда, если ещё не слышали о ней. Когда выполните следующие операции

import pandas as pd
df1 = pd.DataFrame({ 'a':[0,0,0], 'b': [1,1,1]})
df2 = df1
df2['a'] = df2['a'] + 1
df1.head()

обнаружите, что df1 изменён. Это потому, что df2 = df1 не делает копию df1 и не присваивает это значение df2, а устанавливает указатель, который ссылается на df1. Таким образом, любые изменения в df2 приведут к изменениям в df1. Чтобы это исправить, сделайте

df2 = df1.copy()

или же

from copy import deepcopy
df2 = deepcopy(df1)

map

Это классная команда для простого преобразования данных. Определяете словарь, в котором «ключами» являются старые значения, а «значениями» – новые значения:

level_map = {1: 'high', 2: 'medium', 3: 'low'}
df['c_level'] = df['c'].map(level_map)

Некоторые примеры:

  • трансформация true, false в 1, 0 для моделирования;
  • определение уровней;
  • установленные пользователем кодировки.

применять или не применять функцию apply?

Нужен новый столбец с несколькими другими столбцами в качестве входных данных? Функция apply спешит на помощь!

def rule(x, y):
    if x == 'high' and y > 10:
         return 1
    else:
         return 0
df = pd.DataFrame({ 'c1':[ 'high' ,'high', 'low', 'low'], 'c2': [0, 23, 17, 4]})
df['new'] = df.apply(lambda x: rule(x['c1'], x['c2']), axis =  1)
df.head()

Здесь определена функцию с двумя входными переменными, и с помощью функции apply применяем к столбцам 'c1' и 'c2'.

Но проблема применения «apply» в том, что иногда это слишком медленно. Например, вам надо рассчитать максимум для 'c1' и 'c2'. Конечно, можно сделать

df['maximum'] = df.apply(lambda x: max(x['c1'], x['c2']), axis = 1)

но это будет намного медленнее, чем

df['maximum'] = df[['c1','c2']].max(axis =1)

Вывод: не используйте apply, если можете выполнить ту же работу с помощью других встроенных функций, которые часто работают быстрее. Например, если нужно округлить столбец 'c' до целых чисел, выполните round(df['c'], 0) или df['c'].round(0) вместо apply: df.apply(lambda x: round(x['c'], 0), axis = 1).

value counts

Команда для проверки распределения значений. Чтобы проверить возможные значения и частоту каждого отдельного значения в столбце 'c', выполните:

df['c'].value_counts()

Некоторые полезные трюки и аргументы этой функции:

  1. normalize = True – проверить частоту вместо подсчёта.
  2. dropna = False – включить пропущенные значения в статистику.
  3. df['c'].value_counts().reset_index() – преобразовать таблицу статистики в объект Pandas DataFrame.
  4. df['c'].value_counts().reset_index().sort_values(by='index') – показывать статистику, отсортированную по уникальным значениям в столбце 'c' вместо количества.

Количество пропущенных значений

При построении моделей часто надо исключить строку с большим количеством пропущенных значений или строки со всеми пропущенными значениями. Используйте .isnull() и .sum() для подсчёта количества пропущенных значений в указанных столбцах:

import pandas as pd
import numpy as np
df = pd.DataFrame({ 'id': [1,2,3], 'c1':[0,0,np.nan], 'c2': [np.nan,1,1]})
df = df[['id', 'c1', 'c2']]
df['num_nulls'] = df[['c1', 'c2']].isnull().sum(axis=1)
df.head()

Выбрать строки с конкретными идентификаторами

В SQL используем SELECT * FROM… WHERE ID в («A001», «C022»,…) и получаем записи с конкретными идентификаторами. Если хотите сделать то же с помощью Python библиотеки Pandas, используйте

df_filter = df['ID'].isin(['A001','C022',...])
df[df_filter]

Процентильные группы в Python Pandas

У нас есть числовой столбец. Хотим классифицировать значения в этом столбце по группам:

  • верхние 5% в группе 1
  • 5–20% в группе 2
  • 20–50% в группе 3
  • нижние 50% в группе 4

Конечно, можно сделать это с помощью pandas.cut, но рассмотрим другой вариант

import numpy as np
cut_points = [np.percentile(df['c'], i) for i in [50, 80, 95]]
df['group'] = 1
for i in range(3):
    df['group'] = df['group'] + (df['c'] < cut_points[i])
# или <= cut_points[i]

который быстро запускается, потому что не применяется функция apply.

to_csv

Опять же, это команда, которую все будут использовать. Здесь расскажем о двух трюках. Первый:

print(df[:5].to_csv())

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

Ещё один трюк касается смешения целых чисел и пропущенных значений. Если столбец содержит как пропущенные значения, так и целые числа, типом данных по-прежнему будет float, а не int. Когда экспортируете таблицу, добавьте float_format = '%. 0f', чтобы округлить числа с плавающей точкой до целых чисел. Используйте этот трюк, когда нужны только целочисленные выходные данные столбцов – так избавитесь от надоедливых '.0'.

Это перевод статьи о трюках библиотеки Python Pandas на Towards Data Science.

Интересуетесь Data Science и Python? Читайте статьи по теме:

Какой трюк пакета Python Pandas попробуете в ближайшее время?

ЛУЧШИЕ СТАТЬИ ПО ТЕМЕ

admin
11 декабря 2018

ООП на Python: концепции, принципы и примеры реализации

Программирование на Python допускает различные методологии, но в его основе...
admin
14 июля 2017

Пишем свою нейросеть: пошаговое руководство

Отличный гайд про нейросеть от теории к практике. Вы узнаете из каких элеме...