python pandas: применить функцию с аргументами к серии

150

Я хочу применить функцию с аргументами к серии в python pandas:

x = my_series.apply(my_function, more_arguments_1)
y = my_series.apply(my_function, more_arguments_2)
...

В документации описывается поддержка метода apply, но он не принимает никаких аргументов. Есть ли другой метод, принимающий аргументы? Или мне не хватает простого обходного пути?

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

Абэ
источник
3
Почему бы просто не использовать functools.partial, или starmap?
Джоэл Корнетт

Ответы:

176

Более новые версии панд сделать позволяют передать дополнительные параметры (см новой документации ). Итак, теперь вы можете:

my_series.apply(your_function, args=(2,3,4), extra_kw=1)

Позиционные аргументы добавляются после элемента ряда.


Для более старой версии панд:

В документации это ясно объясняется. Метод apply принимает функцию Python, которая должна иметь единственный параметр. Если вы хотите передать больше параметров, вы должны использовать, functools.partialкак предложил Джоэл Корнетт в его комментарии.

Пример:

>>> import functools
>>> import operator
>>> add_3 = functools.partial(operator.add,3)
>>> add_3(2)
5
>>> add_3(7)
10

Вы также можете передавать аргументы ключевого слова, используя partial.

Другой способ - создать лямбду:

my_series.apply((lambda x: your_func(a,b,c,d,...,x)))

Но я думаю, что partialлучше использовать.

Бакуриу
источник
12
Для метода apply DataFrame принимает argsаргумент, который является кортежем, содержащим дополнительные позиционные аргументы или ** kwds для именованных. Я создал проблему, чтобы иметь это также для Series.apply () github.com/pydata/pandas/issues/1829
Воутер Овермайр
29
Функция была реализована, будет в следующем выпуске pandas
Уэс МакКинни
4
Это хороший ответ, но первые 2/3 его уже устарели. ИМО, этот ответ можно было бы хорошо обновить, просто представляя собой ссылку на новую документацию плюс краткий пример того, как использовать с аргументами позиции и / или ключевого слова. Просто FWIW, а не критика исходного ответа, просто выиграет от обновления IMO, тем более что это часто читаемый ответ.
JohnE
@watsonic С тех пор документация была обновлена, и нажатие на старые ссылки ведет к текущей документации, которая теперь очень хорошо отвечает на вопрос.
JohnE
Примечание. Если вы передаете, например 'abc', один строковый аргумент , он args=('abc')будет оцениваться как три аргумента ('a', 'b', 'c'). Чтобы избежать этого, вы должны передать кортеж, содержащий строку, и для этого включить запятую в конце:args=('abc',)
Rocky K
84

Шаги:

  1. Создать фрейм данных
  2. Создать функцию
  3. Используйте именованные аргументы функции в заявлении о применении.

пример

x=pd.DataFrame([1,2,3,4])  

def add(i1, i2):  
    return i1+i2

x.apply(add,i2=9)

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

    0
0  10
1  11
2  12
3  13

Пояснение:

Функция «добавить» имеет два параметра: i1, i2. Первый параметр будет значением во фрейме данных, а второй - тем, что мы передаем функции «apply». В этом случае мы передаем «9» функции apply с помощью ключевого слова аргумент «i2».

Кулак ярости
источник
2
Именно то, что я искал. Примечательно, что это не требует создания специальной функции только для обработки Series (или df). Отлично!
Коннор
Единственный оставшийся вопрос: как передать аргумент ключевого слова первому аргументу в add (i1) и выполнить итерацию с i2?
Коннор
Я думаю, что это лучший ответ
crypdick
46
Series.apply(func, convert_dtype=True, args=(), **kwds)

args : tuple

x = my_series.apply(my_function, args = (arg1,))
dani_g
источник
11
Благодарность! Можете ли вы объяснить, почему args = (arg1,) нужна запятая после первого аргумента?
DrMisha
22
@MishaTeplitskiy, вам нужна запятая, чтобы Python понял, что содержимое скобок является кортежем длиной 1.
prooffreader
3
А как насчет добавления аргументов для func. Итак, если я хочу подать заявку, pd.Series.mean(axis=1)как мне вставить axis=1?
Little Bobby Tables
1
В качестве примечания, вы также можете добавить аргумент ключевого слова без использования параметра <args> (например: x = my_series.apply (my_function, keyword_arg = arg1), где <keyword_arg> входит в число входных параметров my_function)
lev
1
этот ответ слишком короткий и ничего не объясняет
FistOfFury
23

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

Например, давайте создадим функцию, которая возвращает True для значений от 3 до 6 и False в противном случае.

s = pd.Series(np.random.randint(0,10, 10))
s

0    5
1    3
2    1
3    1
4    6
5    0
6    3
7    4
8    9
9    6
dtype: int64

s.apply(lambda x: x >= 3 and x <= 6)

0     True
1     True
2    False
3    False
4     True
5    False
6     True
7     True
8    False
9     True
dtype: bool

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

def between(x, low, high):
    return x >= low and x =< high

Мы можем воспроизвести вывод первой функции, передав безымянные аргументы в args:

s.apply(between, args=(3,6))

Или мы можем использовать названные аргументы

s.apply(between, low=3, high=6)

Или даже сочетание того и другого

s.apply(between, args=(3,), high=6)
Тед Петру
источник