Погружение в фильтрацию, манипулирование и функционирование

Вспомните, когда вы в последний раз работали с хорошо отформатированным набором данных. Хорошо названные столбцы, минимальное количество пропущенных значений и правильная организация. Это приятное чувство — почти освобождение — быть благословленным данными, которые вам не нужно очищать и преобразовывать.

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

Нет такой вещи, как чистые данные (в их первоначальном виде). Если вы специалист по данным, вы знаете это. Если вы только начинаете, вы должны принять это. Вам нужно будет преобразовать ваши данные, чтобы работать с ними эффективно.

Давайте поговорим о трех способах сделать это.

Фильтрация, но правильное объяснение

Давайте поговорим о фильтрации — но немного глубже, чем вы, возможно, привыкли делать. Как одна из наиболее распространенных и полезных операций преобразования данных, эффективная фильтрация является обязательным навыком для любого специалиста по данным. Если вы знаете Pandas, вероятно, это одна из первых операций, которую вы научились выполнять.

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

Мы собираемся отфильтровать все баллы ниже 90, потому что в этот день мы решили быть плохо подготовленными преподавателями, которые обслуживают только лучших учеников (пожалуйста, никогда не делайте этого). Стандартная строка кода для этого выглядит следующим образом:

grades[grades['Score'] >= 90]

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

grades['Score'] >= 90

Ах хорошо. В этом есть смысл. Похоже, что эта строка кода возвращает объект Pandas Series, который содержит логические ( True / False ) значения, определяемые тем, что <row_score> >= 90 возвращает для каждой отдельной строки. Это ключевой промежуточный шаг. После этого именно эта серия логических значений передается во внешние скобки и соответствующим образом фильтрует все строки.

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

grades.loc[grades['Score'] >= 90]

Существует ряд причин, по которым мы могли бы выбрать использование loc (одна из которых заключается в том, что он фактически позволяет нам фильтровать строки и столбцы с помощью одной операции), но это открывает операции ящика Пандоры с пандами, которые лучше оставить для другой статьи. .

На данный момент важная цель обучения заключается в следующем: когда мы фильтруем в Pandas, запутанный синтаксис не является какой-то странной магией. Нам просто нужно разбить его на два составляющих этапа: 1) получение логической серии строк, которые удовлетворяют нашему условию, и 2) использование серии для фильтрации всего DataFrame.

Почему это полезно, спросите вы? Ну, вообще говоря, это может привести к запутанным ошибкам, если вы просто используете операции, не понимая, как они на самом деле работают. Фильтрация — полезная и невероятно распространенная операция, и теперь вы знаете, как она работает.

Давайте двигаться дальше.

Красота лямбда-функций

Иногда ваши данные требуют преобразований, которые просто не встроены в функциональность Pandas. Как бы вы ни старались, никакие поиски Stack Overflow или тщательное изучение документации Pandas не помогут найти решение вашей проблемы.

Введите лямбда-функции — полезная функция языка, которая прекрасно интегрируется с Pandas.

В качестве краткого обзора, вот как работают лямбда-выражения:

>>> add_function = lambda x, y: x + y
>>> add_function(2, 3)
5

Лямбда-функции ничем не отличаются от обычных функций, за исключением того, что они имеют более лаконичный синтаксис:

  • Имя функции слева от знака равенства.
  • Ключевое слово lambda справа от знака равенства (аналогично ключевому слову def в традиционном определении функции Python, это позволяет Python узнать, что мы определяем функцию).
  • Параметры после ключевого слова lambda слева от двоеточия.
  • Возвращаемое значение справа от двоеточия.

Теперь давайте применим лямбда-функции к реальной ситуации.

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

Теперь, как Высочества Master Data в этой компании, мы получили совершенно секретную информацию: каждому в этой компании будет предоставлено повышение на 10% плюс дополнительные 1000 долларов. Вероятно, это слишком специфический расчет, чтобы найти для него конкретный метод, но достаточно простой с лямбда-функцией:

update_income = lambda num: num + (num * .10) + 1000

Затем все, что нам нужно сделать, это использовать эту функцию с функцией Pandas apply, которая позволяет нам применять функцию к каждому элементу выбранной серии:

monies['New Income'] = monies['Income'].apply(update_income)
monies

Готово! Великолепный новый DataFrame, содержащий именно ту информацию, которая нам была нужна, и все это в двух строках кода. Чтобы сделать это еще более кратким, мы могли бы даже определить лямбда-функцию внутри apply напрямую — классный совет, о котором стоит помнить.

Я буду держать точку здесь простой.

Лямбды чрезвычайно полезны, и поэтому вы должны их использовать. Наслаждаться!

Функции манипулирования строкой серии

В предыдущем разделе мы говорили об универсальности лямбда-функций и обо всех интересных вещах, которые они могут помочь вам выполнить с вашими данными. Это превосходно, но будьте осторожны, чтобы не увлечься. Невероятно часто настолько увязнуть в одном знакомом способе выполнения задач, что вы упускаете более простые ярлыки, которыми Python благословил программистов. Конечно, это относится не только к лямбда-выражениям, но мы пока остановимся на этом.

Например, предположим, что у нас есть следующий DataFrame с именем names , в котором хранятся имена и фамилии людей:

Теперь, из-за нехватки места в нашей базе данных, мы решаем, что вместо того, чтобы хранить всю фамилию человека, более эффективно просто хранить его последний инициал. Таким образом, нам нужно соответствующим образом преобразовать столбец 'Last Name'. С лямбда-выражениями наша попытка сделать это может выглядеть примерно так:

names['Last Name'] = names['Last Name'].apply(lambda s: s[:1])
names

Это явно работает, но немного неуклюже и, следовательно, не настолько питонично, как могло бы быть. К счастью, при всей красоте функций манипулирования строками в Pandas есть другой, более элегантный способ (для целей следующей строки кода просто продолжайте и предположим, что мы еще не изменили столбец 'Last Name' с помощью приведенного выше кода):

names['Last Name'] = names['Last Name'].str[:1]
names

Та-да! Свойство .str серии Pandas позволяет нам соединять каждую строку в серии с указанной строковой операцией, как если бы мы работали с каждой строкой по отдельности.

Но подождите, станет лучше. Поскольку .str эффективно позволяет нам получить доступ к обычной функциональности строки через Series, мы также можем применять ряд строковых функций, чтобы ускорить обработку наших данных! Например, предположим, что мы решили преобразовать оба столбца в нижний регистр. Следующий код выполняет эту работу:

names['First Name'] = names['First Name'].str.lower()
names['Last Name'] = names['Last Name'].str.lower()
names

Гораздо проще, чем мучиться с определением собственных лямбда-функций и вызовом внутри них строковых функций. Не то чтобы я не любил лямбда-выражения — но всему есть свое место, и простота всегда должна быть в приоритете в Python.

Я привел здесь только несколько примеров, но в вашем распоряжении большая коллекция строковых функций [1].

Используйте их свободно. Они превосходны.

Заключительные мысли и итоги

Вот вам небольшая шпаргалка по преобразованию данных:

  1. Фильтруйте так, как считаете нужным. Узнайте, что происходит на самом деле, чтобы знать, что вы делаете.
  2. Любите свои лямбды. Они могут помочь вам манипулировать данными удивительными способами.
  3. Pandas любит строки так же сильно, как и вы. Есть много встроенного функционала — вы также можете использовать его.

И последний совет: не существует «правильного» способа фильтрации набора данных. Это зависит от имеющихся данных, а также от уникальной проблемы, которую вы хотите решить. Тем не менее, хотя нет определенного метода, которому вы могли бы следовать каждый раз, в вашем распоряжении есть полезная коллекция инструментов. В этой статье я рассмотрел три из них.

Я призываю вас выйти и найти еще несколько.

Хотите преуспеть в Python? Получите эксклюзивный бесплатный доступ к моим простым и понятным руководствам здесь. Хотите читать неограниченное количество историй на Medium? Зарегистрируйтесь по моей реферальной ссылке ниже!



Рекомендации

[ 1] https://www.aboutdatablog.com/post/10-most-useful-string-functions-in-pandas