Эффективная обработка данных с помощью Apply() в Pandas
Функция apply() - это мощный инструмент в Python для анализа данных и манипулирования ими. Это ценный инструмент для инструментария любого аналитика, поскольку он может быть легко интегрирован с другими функциями Pandas и пользовательскими функциями для выполнения сложных преобразований данных. В этой статье мы узнаем, как использовать функцию apply() в Pandas для эффективной и гибкой обработки данных.
Обзор функции Apply()
Функция apply()
позволяет выполнять ряд преобразований ваших данных. Вы можете определить свою собственную функцию для определенных задач, таких как манипуляции со строками, сложные операции или пользовательские вычисления. После определения вы можете использовать apply()
их в своем DataFrame без необходимости кодировать их снова каждый раз, когда вам нужно их использовать.
Точно так же вы можете определить лямбда-функцию , которая является анонимной и быстрой операцией, создаваемой на лету. Вы можете передать его apply()
, чтобы мгновенно использовать его для своих данных.
Функцию apply()
также можно использовать со встроенными функциями, предварительно упакованными в Python. Pandas Series и DataFrames совместимы с использованием apply()
.
Использование Apply() в серии
Давайте определим серию среднемесячных температур (в градусах Цельсия) для города за год, импортировав пакет Pandas и используя класс Series()
:
import pandas as pd city_temps = pd.Series([1, 4, 8, 9, 14, 25, 31, 35, 32, 25, 11, 2])
Мы можем создать пользовательскую функцию для преобразования этих температур в шкалу Фаренгейта:
def celsius_to_fahrenheit(celsius): fahrenheit = (celsius * 9/5) + 32 return fahrenheit
Приведенная выше функция принимает числовое значение температуры в градусах Цельсия и преобразует его в градусы Фаренгейта. Теперь мы можем преобразовать каждый элемент нашей серии:
temp_fahrenheit = city_temps.apply(celsius_to_fahrenheit) print(temp_fahrenheit)
Результатом является ряд, содержащий преобразованные значения городских температур:
0 33.8 1 39.2 2 46.4 3 48.2 4 57.2 5 77.0 6 87.8 7 95.0 8 89.6 9 77.0 10 51.8 11 35.6 dtype: float64
Применение apply()
к DataFrame
Использование apply()
обеспечивает гибкость добавления или управления столбцами в Pandas DataFrames. Рассмотрим DataFrame со среднемесячными температурами в течение года для двух городов:
data = {'City 1': [1, 4, 8, 9, 14, 25, 31, 35, 32, 25, 11, 2], 'City 2': [19, 23, 30, 31, 35, 40, 45, 39, 30, 25, 15, 10] } # Create the DataFrame df = pd.DataFrame(data) print(df)
DataFrame выглядит следующим образом:
City 1 City 2 0 1 19 1 4 23 2 8 30 3 9 31 4 14 35 5 25 40 6 31 45 7 35 39 8 32 30 9 25 25 10 11 15 11 2 10
Мы можем использовать apply()
нашу функцию в df
DataFrame и создать новый столбец City 1 Fahrenheit
:
df['City 1 Fahrenheit'] = df['City 1'].apply(celsius_to_fahrenheit) # Print the DataFrame print(df)
Трансформация прошла успешно:
City 1 City 2 City 1 Fahrenheit 0 1 19 33.8 1 4 23 39.2 2 8 30 46.4 3 9 31 48.2 4 14 35 57.2 5 25 40 77.0 6 31 45 87.8 7 35 39 95.0 8 32 30 89.6 9 25 25 77.0 10 11 15 51.8 11 2 10 35.6
Важным примечанием здесь является использование параметра axis
внутри apply()
функции, который указывает, хотим ли мы выполнить операцию со строками или столбцами DataFrame. При указании axis=0
операция axis=1
применяется к каждому столбцу, а к каждой строке. В нашем предыдущем примере axis=0
использовалось значение по умолчанию, поскольку мы не передавали значение для axis
. Это применило нашу функцию к каждому столбцу и вернуло значение для каждой строки.
Давайте явно передадим axis=1
нашей apply()
пользовательской функции все столбцы в DataFrame. Мы создадим два новых столбца, применяя преобразование к каждой строке.
data = {'City 1': [1, 4, 8, 9, 14, 25, 31, 35, 32, 25, 11, 2], 'City 2': [19, 23, 30, 31, 35, 40, 45, 39, 30, 25, 15, 10] } df = pd.DataFrame(data) df[['City 1 Fahrenheit', 'City 2 Fahrenheit']] = df.apply( lambda row: pd.Series( [celsius_to_fahrenheit(row['City 1']), celsius_to_fahrenheit(row['City 2'])]), axis=1 ) print(df)
Здесь мы использовали лямбда-выражение, чтобы принимать каждую строку в качестве входных данных, используя axis=1
и возвращая объект Series со значениями по Фаренгейту. Эта результирующая серия была назначена столбцам «Город 1 по Фаренгейту» и «Город 2 по Фаренгейту» в DataFrame.
Определите тип возвращаемого значения функции Apply()
Возможно, вы уже заметили, что apply()
в наших предыдущих примерах всегда возвращался ряд. Как правило, результатом применения функции является объект Series, который поддерживает структуру индексации исходных данных. Однако мы можем использовать этот result_type
параметр и установить для него значение «расширить», что указывает на возврат DataFrame. Это особенно полезно, когда нам нужно изменить структуру данных или применить функции, которые генерируют несколько значений.
Давайте изменим наш предыдущий пример, чтобы увидеть, как мы можем вернуть DataFrame, используя result_type
параметр.
data = {'City 1': [1, 4, 8, 9, 14, 25, 31, 35, 32, 25, 11, 2], 'City 2': [19, 23, 30, 31, 35, 40, 45, 39, 30, 25, 15, 10] } df = pd.DataFrame(data) df[['City 1 (Fahrenheit)', 'City 2 (Fahrenheit)']] = df.apply(lambda row: celsius_to_fahrenheit(row), axis=1, result_type='expand') print(df)
Вывод такой же, как мы получили ранее:
City 1 City 2 City 1 (Fahrenheit) City 2 (Fahrenheit) 0 1 19 33.8 66.2 1 4 23 39.2 73.4 2 8 30 46.4 86.0 3 9 31 48.2 87.8 4 14 35 57.2 95.0 5 25 40 77.0 104.0 6 31 45 87.8 113.0 7 35 39 95.0 102.2 8 32 30 89.6 86.0 9 25 25 77.0 77.0 10 11 15 51.8 59.0 11 2 10 35.6 50.0
Понятно, что это result_type
позволяет нам значительно упростить преобразование новых столбцов, поскольку нам больше не нужно явно манипулировать выводом, чтобы преобразовать его в структуру DataFrame.
Вопросы производительности
Хотя эта apply()
функция кажется мощным инструментом для упрощения преобразования данных, она лучше подходит для определенных типов задач. В дополнение к пользовательским преобразованиям данных или операциям по строкам и столбцам, как упоминалось ранее, его также можно использовать для объединения столбцов для очистки данных или разработки функций. Кроме того, это полезно для обработки пропущенных значений, поскольку мы можем определить и применить пользовательские методы вменения.
Стоит рассмотреть альтернативные подходы, apply()
если вам нужна оптимальная производительность для больших наборов данных или задач, требующих больших вычислительных ресурсов. Вы должны использовать встроенные векторизованные операции везде, где это возможно. Например, вы можете использовать sum()
метод вместо apply(sum)
. Вы также можете использовать встроенные строковые операции, такие как str.replace()
и условные операции, например, where()
для эффективных агрегаций и групповых операций. Кроме того, рассмотрите пакеты Python, такие как Swifter или Dask, которые используют параллельную обработку для эффективной работы с большими наборами данных. В зависимости от размера вашего набора данных и доступных вычислительных ресурсов эти альтернативы могут значительно повысить производительность задач обработки данных по сравнению с использованием apply()
в одиночку.
Заключение
Таким образом, apply()
функция служит ценным ресурсом для манипулирования данными, особенно в рутинных задачах, требующих повторяющегося кода. Эта функция обеспечивает бесшовную интеграцию пользовательских или встроенных функций с сериями Pandas и DataFrames. Выявление возможностей использования этой apply()
функции может значительно повысить вашу производительность при выполнении повседневных задач.