python - nueva - ¿Cómo uso la función ''aplicar'' de Pandas a múltiples columnas?
seleccionar columnas en pandas (4)
Digamos que queremos aplicar una función add5 a las columnas ''a'' y ''b'' de DataFrame df
def add5(x):
return x+5
df[[''a'', ''b'']].apply(add5)
Tengo algunos problemas con la función aplicar Pandas, cuando se utilizan varias columnas con el siguiente marco de datos
df = DataFrame ({''a'' : np.random.randn(6),
''b'' : [''foo'', ''bar''] * 3,
''c'' : np.random.randn(6)})
y la siguiente función
def my_test(a, b):
return a % b
Cuando intento aplicar esta función con:
df[''Value''] = df.apply(lambda row: my_test(row[a], row[c]), axis=1)
Aparece el mensaje de error:
NameError: ("global name ''a'' is not defined", u''occurred at index 0'')
No entiendo este mensaje, definí el nombre correctamente.
Agradecería mucho cualquier ayuda sobre este tema
Actualizar
Gracias por tu ayuda. De hecho hice algunos errores de sintaxis con el código, el índice debería ponerse ''''. Sin embargo, todavía tengo el mismo problema al usar una función más compleja como:
def my_test(a):
cum_diff = 0
for ix in df.index():
cum_diff = cum_diff + (a - df[''a''][ix])
return cum_diff
Gracias
Parece que olvidaste el ''''
de tu cadena.
In [43]: df[''Value''] = df.apply(lambda row: my_test(row[''a''], row[''c'']), axis=1)
In [44]: df
Out[44]:
a b c Value
0 -1.674308 foo 0.343801 0.044698
1 -2.163236 bar -2.046438 -0.116798
2 -0.199115 foo -0.458050 -0.199115
3 0.918646 bar -0.007185 -0.001006
4 1.336830 foo 0.534292 0.268245
5 0.976844 bar -0.773630 -0.570417
Por cierto, en mi opinión, el siguiente camino es más elegante:
In [53]: def my_test2(row):
....: return row[''a''] % row[''c'']
....:
In [54]: df[''Value''] = df.apply(my_test2, axis=1)
Si solo desea calcular (columna a)% (columna b), no necesita apply
, simplemente hágalo directamente:
In [7]: df[''a''] % df[''c'']
Out[7]:
0 -1.132022
1 -0.939493
2 0.201931
3 0.511374
4 -0.694647
5 -0.023486
Name: a
Todas las sugerencias anteriores funcionan, pero si desea que sus cálculos sean más eficientes, debe aprovechar las operaciones numpy vectoriales (ref) .
import pandas as pd
import numpy as np
df = pd.DataFrame ({''a'' : np.random.randn(6),
''b'' : [''foo'', ''bar''] * 3,
''c'' : np.random.randn(6)})
#######
# pandas.apply()
%%timeit
def my_test2(row):
return row[''a''] % row[''c'']
df[''Value''] = df.apply(my_test2, axis=1)
La carrera más lenta tomó 7.49 veces más que la más rápida. Esto podría significar que se está almacenando en caché un resultado intermedio. 1000 bucles, lo mejor de 3: 481 μs por ciclo
############
# vectorize pandas.apply()
%%timeit
df[''a''] % df[''c'']
La carrera más lenta tomó 458.85 veces más que la más rápida. Esto podría significar que se está almacenando en caché un resultado intermedio. 10000 bucles, lo mejor de 3: 70,9 μs por ciclo
#############
# vectorize numpy arrays
%%timeit
df[''a''].values % df[''c''].values
La carrera más lenta tomó 7.98 veces más que la más rápida. Esto podría significar que se está almacenando en caché un resultado intermedio. 100000 bucles, lo mejor de 3: 6,39 μs por ciclo
Así que la vectorización usando matrices numpy mejoró la velocidad en casi dos órdenes de magnitud.