Python pandas: aplica una función con argumentos a una serie

147

Quiero aplicar una función con argumentos a una serie en pandas python:

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

La documentación describe el soporte para un método de aplicación, pero no acepta ningún argumento. ¿Hay algún método diferente que acepte argumentos? Alternativamente, ¿me estoy perdiendo una solución simple?

Actualización (octubre de 2017):apply() tenga en cuenta que, dado que esta pregunta se hizo originalmente, los pandas se actualizaron para manejar argumentos posicionales y de palabras clave y el enlace de documentación anterior ahora lo refleja y muestra cómo incluir cualquier tipo de argumento.

Abe
fuente
3
¿Por qué no solo usar functools.partial, o starmap?
Joel Cornett

Respuestas:

170

Las nuevas versiones de los pandas hacen permiten pasar argumentos adicionales (véase la nueva documentación ). Entonces ahora puedes hacer:

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

Los argumentos posicionales se agregan después del elemento de la serie.


Para versiones anteriores de pandas:

La documentación explica esto claramente. El método apply acepta una función python que debería tener un solo parámetro. Si desea pasar más parámetros, debe usar functools.partialsegún lo sugerido por Joel Cornett en su comentario.

Un ejemplo:

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

También puede pasar argumentos de palabras clave usando partial.

Otra forma sería crear una lambda:

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

Pero creo que usar partiales mejor.

Bakuriu
fuente
12
Para un DataFrame, el método de aplicación acepta argsargumentos, que es una tupla que contiene argumentos posicionales adicionales o ** kwds para los nombrados. Creé un problema para tener esto también para Series.apply () github.com/pydata/pandas/issues/1829
Wouter Overmeire
28
La característica ha sido implementada, será en el próximo lanzamiento de pandas
Wes McKinney
44
Esta es una buena respuesta, pero los primeros 2/3 están realmente obsoletos ahora. En mi opinión, esta respuesta podría actualizarse con solo un enlace a la nueva documentación más un breve ejemplo de cómo usar con argumentos de posición y / o palabras clave. Solo FWIW y no una crítica de la respuesta original, solo se beneficiaría de una actualización IMO, especialmente porque es una respuesta que se lee con frecuencia.
JohnE
@watsonic La documentación se ha actualizado desde entonces y al hacer clic en los enlaces anteriores se accede a la documentación actual que ahora responde muy bien a la pregunta.
JohnE
Nota: Si está pasando un argumento de cadena única, por ejemplo 'abc', args=('abc')se evaluará como tres argumentos ('a', 'b', 'c'). Para evitar esto, debe pasar una tupla que contiene la cadena, y para hacerlo, incluya una coma final:args=('abc',)
Rocky K
82

Pasos:

  1. Crear un marco de datos
  2. Crear una función
  3. Use los argumentos nombrados de la función en la instrucción de aplicación.

Ejemplo

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

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

x.apply(add,i2=9)

El resultado de este ejemplo es que cada número en el marco de datos se agregará al número 9.

    0
0  10
1  11
2  12
3  13

Explicación:

La función "agregar" tiene dos parámetros: i1, i2. El primer parámetro será el valor en el marco de datos y el segundo es lo que pasemos a la función "aplicar". En este caso, estamos pasando "9" a la función de aplicación utilizando el argumento de palabra clave "i2".

Puño de la furia
fuente
2
Exactamente lo que estaba buscando. Notablemente, esto no requiere crear una función personalizada solo para manejar una Serie (o df). ¡Perfecto!
Connor
La única pregunta que queda es: ¿Cómo pasar un argumento de palabra clave al primer argumento en add (i1) e iterar con i2?
Connor
Creo que esta es la mejor respuesta
crypdick
43
Series.apply(func, convert_dtype=True, args=(), **kwds)

args : tuple

x = my_series.apply(my_function, args = (arg1,))
dani_g
fuente
11
¡Gracias! ¿Puedes explicar por qué args = (arg1,) necesita una coma después del primer argumento?
DrMisha
21
@MishaTeplitskiy, necesitas la coma para que Python entienda el contenido de los paréntesis para ser una tupla de longitud 1.
prooffreader
3
¿Qué hay de poner en argumentos para el func. Entonces, si deseo presentar una solicitud, pd.Series.mean(axis=1)¿cómo ingreso el axis=1?
Little Bobby Tables
1
Como nota al margen, también puede agregar un argumento de palabra clave sin usar el parámetro <args> (por ejemplo: x = my_series.apply (my_function, keyword_arg = arg1), donde <keyword_arg> está entre los parámetros de entrada de my_function)
lev
1
esta respuesta es demasiado corta y no explica nada
FistOfFury
23

Puede pasar cualquier número de argumentos a la función que applyestá llamando a través de argumentos sin nombre, pasados ​​como una tupla al argsparámetro, o mediante otros argumentos de palabras clave capturados internamente como un diccionario por el kwdsparámetro.

Por ejemplo, construyamos una función que devuelva True para valores entre 3 y 6, y False en caso contrario.

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

Esta función anónima no es muy flexible. Creemos una función normal con dos argumentos para controlar los valores mínimo y máximo que queremos en nuestra Serie.

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

Podemos replicar el resultado de la primera función pasando argumentos sin nombre a args:

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

O podemos usar los argumentos nombrados

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

O incluso una combinación de ambos

s.apply(between, args=(3,), high=6)
Ted Petrou
fuente