Теперь, когда вы узнали о лямбда-функциях в Python, я рассмотрю пример обработки данных.

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

В прошлый раз я подробно объяснил синтаксис лямбда-функции. Я не буду повторять здесь все подробности, но приведу пример более сложной лямбды, прежде чем мы перейдем к данным.

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

def square_list(nums):
     squared_list = []
     for item in nums:
          squared_list.append(item * item)
     return squared_list

Можно ли перевести эту довольно сложную процедуру в лямбда-функцию? Несомненно! Мы просто используем тот же синтаксис и используем нашего хорошего друга, понимание списка:

square_list = lambda nums : [item * item for item in nums]

И вуаля! Мы аккуратно сжали нашу функцию в одну удобочитаемую строку. Быстрое обновление: наш аргумент nums идет слева от двоеточия, наше возвращаемое значение (полное понимание списка, которое создает новый список в квадрате) идет справа от двоеточия, и мы даем функции имя square_list через присваивание переменной синтаксис.

Теперь, когда мы разобрались с этим, давайте рассмотрим конкретный пример применения лямбда-выражений для обработки данных в Pandas. Представьте, что у вас есть следующий DataFrame с именем my_df, который содержит несколько сводных статистических данных о некоторых данных, которые ваш работодатель хочет, чтобы вы проанализировали более глубоко:

    mean   median       standard deviation
0    22      23                 1.7
1    33      25                 2.8
2    44      40                 4.9
3    55      55                 2.0
4    66      78                 1.0

Когда вы просматриваете это, вы понимаете, что хотите возвести столбец standard deviation в квадрат, чтобы вы могли легко просмотреть соответствующие отклонения. С лямбда-выражениями это однострочное задание:

>>> my_df['standard deviation'] = my_df['standard deviation'].apply(lambda x : x * x)
>>> my_df
    mean   median       standard deviation
0    22      23                2.89
1    33      25                7.84
2    44      40               24.01
3    55      55                4.00
4    66      78                1.00

Что именно происходит выше? Итак, функция .apply() принимает некоторую функцию и применяет ее к каждому отдельному значению в выбранном столбце. Здесь, поскольку наша лямбда-функция возводит в квадрат отдельные значения, мы эффективно возводим в квадрат значение стандартного отклонения каждой строки и переназначаем столбец новым значениям. Вам, вероятно, также следует быстро переименовать столбец в «дисперсию», хотя я оставил это здесь.

Затем предположим, что вы хотите преобразовать столбец mean в значения с плавающей запятой, но вы не можете вспомнить функцию, которая это делает (подсказка: это my_df[‘mean’].astype(float)). И, как всегда, вам лень искать (а может быть, у вас просто нет подключения к интернету). Лямбды снова в помощь:

>>> my_df['mean'] = my_df['mean'].apply(lambda x : float(x))
>>> my_df
   mean    median       standard deviation
0  22.0      23                2.89
1  33.0      25                7.84
2  44.0      40               24.01
3  55.0      55                4.00
4  66.0      78                1.00

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

     name    letter grade  score
0   Kayla            A     92
1   Kayla            A     94
2   Kayla            A     97
3   Kayla            B     81
4   Kayla            B     83
5   Kayla            B     85
6    Arif            A     93
7    Arif            B     86
8    Arif            A     99
9    Arif            B     80
10   Arif            A     94
11   Arif            B     88

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

Хорошо, так что это много. Красота этого? Используя лямбда-функции в сочетании с функцией pandas.pivot_table, мы можем выполнить нашу задачу в одной строке кода:

>>> grades_df.pivot_table(index='name', columns='letter grade', values='score', aggfunc = lambda series : (sorted(list(series))[-1] + sorted(list(series))[-2]) / 2)
letter grade     A     B
name
Arif          96.5  87.0
Kayla         95.5  84.0

Здесь есть что распаковать; давайте сделаем это шаг за шагом:

  • Во-первых, мы говорим, что хотим создать сводную таблицу с index, установленным на 'name', и columns, установленным на 'letter grade'. Это означает, что мы хотим, чтобы каждая строка нашей сводной таблицы была именем учащегося, а каждый столбец — буквенной оценкой.
  • Затем мы устанавливаем параметр values равным 'score'. Это означает, что мы рассмотрим значения 'score' для каждой комбинации 'name' и 'letter grade' в сводной таблице. Например, для комбинации 'Arif' и 'A' значения представляют собой серию Pandas, состоящую из значений (93, 99, 94) , поскольку все эти оценки соответствуют строкам, содержащим как 'Arif', так и 'A' в нашем исходном фрейме данных.
  • Наконец, параметр aggfunc — это место, где появляется наша лямбда-функция. Для каждой комбинированной серии, которую мы создали в приведенном выше маркере, aggfunc сообщает Pandas, как мы хотим объединить эти значения в одно значение, которое фактически помещается в соответствующую запись DataFrame. Мы хотели получить среднее из двух лучших результатов. Таким образом, наша лямбда-функция принимает ряд значений, сортирует их, берет два верхних значения (используя индексацию отрицательного списка) и усредняет их. Глядя конкретно на пример 'Arif' и 'A', мы видим, что из ряда (93, 99, 94) мы берем среднее значение 99 и 94, которое дает 96.5 — окончательное значение, которое мы видим в сводной таблице. Аналогичным образом рассчитываются остальные четыре элемента.

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

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

Последние мысли

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

До следующего раза, ребята!

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



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