Вы когда-нибудь сталкивались с трудностями при использовании метода применения панд? Если да, то этот урок для вас.

Метод apply() — это мощный инструмент, который позволяет применять пользовательскую функцию к каждому элементу DataFrame или Series, упрощая сложные операции с данными и вычисления.

В этой статье мы узнаем, как использовать методы Series.apply() и DataFrame.apply(). В чем разница между методами Series.apply() и DataFrame.apply(). Как использовать их с функциями с аргументами и, наконец, когда их использовать.

Оглавление

  1. Метод Series.apply()

2. Использование аргументов в методе Series.apply()

3. Использование ключевых аргументов в методе Series.apply()

4. Разница между методами DataFrame.apply() и Series.apply()

5. Метод DataFrame.apply()

6. Использование аргументов в методе DataFrame.apply()

7. Заключение

1. Метод Series.apply()

Сначала мы поговорим о том, как использовать метод apply() с Pandas Series. Давайте создадим одну серию Pandas для работы.

Здесь я создал одну простую серию Pandas с 5 значениями, то есть 10, 20, 30, 40 и 50.

#Create a Series
s=pd.Series([10,20,30,40,50])
print(s)

Вывод:

0    10
1    20
2    30
3    40
4    50
dtype: int64p

Теперь я хочу применить некоторую функцию, например, квадратный корень, к каждому значению серии. Я могу сделать это с помощью метода Series.apply(). Все, что мне нужно сделать, это вызвать метод apply() с функцией np.sqrt.

s.apply(np.sqrt)

Вывод:

Здесь мы видим, что квадратный корень применяется к каждому значению строки, и мы видим это в выводе.

0    3.162278
1    4.472136
2    5.477226
3    6.324555
4    7.071068
dtype: float64

Мы можем применить ту же функцию, используя лямбда. Посмотрим, как.

s.apply(lambda x:np.sqrt(x))

Вывод приведенной выше строки кода будет таким же, как и предыдущий.

Выход:

0    3.162278
1    4.472136
2    5.477226
3    6.324555
4    7.071068
dtype: float64

Мы также можем использовать нашу пользовательскую функцию с методом apply вместо встроенной. Давайте посмотрим, как мы можем это сделать.

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

#define a custom function
def custom_add_subtract(x):
    if x<30:
        x+=5
    else:
        x-=5
    return x

Теперь вызовите метод apply с именем нашей пользовательской функции в качестве аргумента.

s.apply(custom_add_subtract)

Вывод:

0    15
1    25
2    25
3    35
4    45
dtype: int64

2. Использование аргументов в методе Series.apply()

Теперь я передумал. Я хочу добавить 10 вместо 5, если значение меньше 30, и вычесть 10, если значение больше или равно 30.

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

#define new function for value 10
def custom_add_subtract_10(x):
    if x<30:
        x+=10
    else:
        x-=10
    return x
#apply new custom function
s.apply(custom_add_subtract_10)

Вывод:

0    20
1    30
2    20
3    30
4    40
dtype: int64

Этот процесс будет раздражать, если мне нужно изменить значение несколько раз. Вот где на сцену выходит argsаргумент метода Series.apply().

Чтобы использовать этот параметр, мне нужно определить один позиционный аргумент value в нашем определении пользовательской функции.

#define a custom function with one positional argument
def custom_add_subtract(x,value):
    if x<30:
        x+=value
    else:
        x-=value
    return x

Теперь мы можем использовать аргумент args метода apply для любого пользовательского значения, которое нужно добавлять и вычитать из строки. Давайте посмотрим, как это сделать.

s.apply(custom_add_subtract,args=(4,))

Здесь мы добавляем и вычитаем 4 из строк.

Вывод:

0    14
1    24
2    26
3    36
4    46
dtype: int64

Если я хочу изменить значение на 6, я могу сделать это легко. Мне просто нужно изменить значение в аргументе args.

s.apply(custom_add_subtract,args=(6,))

Вывод:

0    16
1    26
2    24
3    34
4    44
dtype: int64

Примечание: убедитесь, что вы добавили запятую(,)в args=(6,) после ввода значения, иначе вы можете получить ошибку.

s.apply(custom_add_subtract,args=(6))



TypeError: custom_add_subtract() argument after * must be an iterable, not int

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

Посмотрим как?

#new custom function with two positional arguments

def custom_add_subtract(x,value,threshold):
    if x<threshold:
        x+=value
    else:
        x-=value
    return x   

Теперь мне нужно просто изменить значение value и threshold при вызове метода apply().

s.apply(custom_add_subtract, args=(3,15,))

Теперь он будет добавлять 3, если значение строки меньше 15, и вычитать 3, если значение строки больше или равно 15.

Вывод:

0    13
1    17
2    27
3    37
4    47
dtype: int64

если я передам args=(7,35,) при вызове метода применения. Я получу следующий результат.

s.apply(custom_add_subtract, args=(7,35,))

Вывод:

0    17
1    27
2    37
3    33
4    43
dtype: int64

Таким образом, мы можем использовать пользовательские функции с позиционными аргументами при использовании метода apply().

3. Использование аргументов ключевого слова в методе Series.apply()

Теперь мы увидим, как использовать аргументы ключевого слова (**kwargs) с методом Series.apply().

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

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

# Define custom function with keyword arguments
def custom_add_subtract(x,value,threshold,**kwargs): 
    if x<threshold:
        x+=value
    else:
        x-=value
        
    if kwargs.get('m') is not None:
        return x*kwargs['m']
    return x

Если мы передаем m=2 после параметра args, вывод будет умножен на 2.

#Value with Multiply factor m=2
s.apply(custom_add_subtract, args=(9,25),m=2)

Вывод:

0    38
1    58
2    42
3    62
4    82
dtype: int64

Если мы не передадим какое-либо значение, то он вернет вывод без умножения.

#Value without Multiply factor
s.apply(custom_add_subtract, args=(9,25))

Вывод:

0    19
1    29
2    21
3    31
4    41
dtype: int64

Вот как мы можем использовать аргументы ключевых слов с методом apply().

На этом варианты использования метода Pandas Series.apply() завершены. Мы узнали, как использовать метод apply() с функцией, как использовать функцию с одним или несколькими позиционными аргументами, а затем как использовать функцию с ключевыми аргументами. Теперь мы увидим, как использовать метод Pandas DataFrame.apply().

4. Разница между методами Series.apply() и DataFrame.apply()

Прежде чем углубляться в метод DataFrame.apply(). Во-первых, давайте посмотрим, чем DataFrame.apply() отличается от Series.Apply().

  1. Ввод и вывод: Series.apply() работает с каждым элементом Series, а DataFrame.apply() может работать с каждым столбцом или строкой DataFrame. Результатом Series.apply() всегда является Series, а результатом DataFrame.apply() может быть Series (если применяется к одному столбцу) или DataFrame (если применяется к нескольким столбцам).
  2. Аргументы функции: функция, переданная Series.apply(), принимает одно значение в качестве входных данных и возвращает одно значение в качестве выходных данных. Напротив, функция, переданная в DataFrame.apply(), может принимать в качестве входных данных один столбец или строку или DataFrame с несколькими столбцами или строками и может возвращать одно значение, Series или DataFrame.
  3. Область действия: Series.apply() позволяет определить функцию, которая работает только со значениями Series, а DataFrame.apply() позволяет определить функцию, которая может работать со значениями одного или нескольких столбцов или строк.
  4. Параметр оси: параметр axis в Series.apply() всегда имеет значение 0, так как в Series есть только одна ось. Однако для параметра axis в DataFrame.apply() можно установить значение 0 или 1, чтобы применить функцию к строкам или столбцам соответственно.

5. Метод DataFrame.apply()

Хотя метод Series.apply() работает только с каждым элементом серии, тогда как метод DataFrame.apply() может работать со всем фреймом данных, одним или несколькими столбцами и ряды. Посмотрим как?

Прежде всего, давайте создадим один DataFrame для работы.

import pandas as pd

# Create a DataFrame
df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6], 'C': [7, 8, 9]})

df

Вывод:

  A B C
0 1 4 7
1 2 5 8
2 3 6 9

Предположим, мы хотим применить квадратный корень к каждому элементу DataFrame. Мы можем сделать это, следуя команде.

df.apply(np.sqrt)

Вывод:

  A        B        C
0 1.000000 2.000000 2.645751
1 1.414214 2.236068 2.828427
2 1.732051 2.449490 3.000000

Если вы хотите применить какую-либо функцию к каждому столбцу DataFrame, вам нужно указать axis=0 или axis=’index’ в методе apply().

Предположим, я хочу вычислить сумму каждого столбца в DataFrame, для этого после передачи функции np.sum мне нужно передать axis=0 при вызове apply() для DataFrame.

#Calculate sum for each column
df.apply(np.sum, axis=0)

#df.apply(np.sum, axis='index')

Вывод:

A     6
B    15
C    24
dtype: int64

здесь мы вычисляем сумму для каждого столбца:

A: 1+2+3 =6

B: 4+5+6=15

C: 7+8+9=24

Точно так же, если вы хотите применить некоторую функцию к каждой строке DataFrame, вам нужно указать axis=1 или axis=’columns’ в методе apply().

Теперь я хочу рассчитать сумму каждой строки DataFrame. Я могу сделать это, передав axis=1 или axis=’columns’ в методе apply().

#calculate sum of each row
df.apply(np.sum, axis=1)

#df.apply(np.sum, axis='columns')

Вывод:

0    12
1    15
2    18
dtype: int64

здесь мы вычисляем сумму каждой строки:

0: 1+4+7=12

1: 2+5+8=15

2: 3+6+9=18

Используя параметр axis, мы можем указать, следует ли применять функцию к столбцу или строке.

6. Использование аргументов в методе DataFrame.apply()

Теперь мы увидим, как использовать аргументы при использовании метода DataFrame.apply().

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

#Sum of two column
def column_sum(row,col1,col2)
    return row[col1]+row[col2]

Эта функция примет строку DataFrame в качестве первого аргумента и имена столбцов в качестве второго и третьего аргументов. Затем он вернет сумму двух столбцов в качестве вывода.

Сначала я вычислю сумму столбцов A и B. Для этого мне нужно сначала передать нашу пользовательскую функцию column_sum, затем мне нужно передать args=('A', 'B') при вызове apply () метод в DataFrame. Кроме того, нам нужно применить эту функцию к каждой строке, поэтому нам также нужно передать axis=1.

# Apply the function to each row
df.apply(column_diff, axis=1, args=('A', 'B'))

Вывод:

0    5
1    7
2    9
dtype: int64

Аналогично, для вычисления суммы столбцов B и C:

# Apply the function to each row
df.apply(column_diff, axis=1, args=('B', 'C'))

Вывод:

0    11
1    13
2    15
dtype: int64

7. Заключение

В этой статье мы узнали, как использовать метод Series.apply() и метод DataFrame.apply(), разницу между ними и как использовать как с аргументами, так и с аргументами ключевого слова.

Если вы хотите применить какую-то функцию к каждому значению столбца, тогда лучше использовать Series.apply(), а если вы хотите применить какую-то функцию, которая включает две или более строк и столбцов, то лучше использовать метод DataFrame.apply() .

Спасибо за чтение. Открыт для предложений и отзывов.