Estoy creando una función. Una entrada de esta función será un marco de datos de panda y una de sus tareas es realizar algunas operaciones con dos variables de este marco de datos. Estas dos variables no son fijas y quiero tener la libertad de determinarlas utilizando parámetros como entradas de la función fun.
Por ejemplo, suponga que en algún momento las variables que quiero usar son 'var1' y 'var2' (pero en otro momento, podría querer usar otras dos variables). Suponga que estas variables toman valores 1,2,3,4 y quiero reducir df haciendo var1 == 1 y var2 == 1. Mis funciones son así
def fun(df , var = ['input_var1', 'input_var2'] , val):
df = df.rename(columns={ var[1] : 'aux_var1 ', var[2]:'aux_var2'})
# Other operations
df = df.loc[(df.aux_var1 == val ) & (df.aux_var2 == val )]
# end of operations
# recover
df = df.rename(columns={ 'aux_var1': var[1] ,'aux_var2': var[2]})
return df
Cuando uso la función fun, tengo el error
fun(df, var = ['var1','var2'], val = 1)
IndexError: list index out of range
En realidad, quiero hacer otras operaciones más complejas y no describí estas operaciones para no extender la pregunta. Quizás el simple ejemplo anterior tiene una solución que no necesita cambiar el nombre de las variables. Pero tal vez esta solución no funcione con las operaciones que realmente quiero hacer. Entonces, primero, necesariamente me gustaría corregir el error al cambiar el nombre de las variables. Si desea dar otra solución más elegante que no necesita cambiar de nombre, se lo agradezco también, pero le agradeceré si, además de la solución elegante, me ofrece la solución para cambiar el nombre.
3 respuestas
Las escuchas de Python están indexadas a cero, es decir, el índice del primer elemento es 0. Simplemente cambie las líneas:
df = df.rename(columns={ var[1] : 'aux_var1 ', var[2]:'aux_var2'})
df = df.rename(columns={ 'aux_var1': var[1] ,'aux_var2': var[2]})
Para
df = df.rename(columns={ var[0] : 'aux_var1 ', var[1]:'aux_var2'})
df = df.rename(columns={ 'aux_var1': var[0] ,'aux_var2': var[1]})
Respectivamente
Como se ha mencionado en otras respuestas, el error que está recibiendo se debe a la indexación 0 de las listas de Python, es decir, si desea acceder al primer elemento de la lista var
, lo hace tomando el { Índice {X1}} en lugar del índice 1
: var[0]
.
Sin embargo, con respecto al tema del cambio de nombre, puede realizar el filtrado del marco de datos de pandas sin ningún cambio de nombre de columna. Puedo ver que está accediendo a la columna como un atributo del marco de datos, sin embargo, puede lograr lo mismo mediante el uso del método __getitem__
, que se usa más comúnmente con corchetes, p. Ej. df[var[0]]
.
Si desea tener más generalidad sobre su función sin que ocurra ningún cambio de nombre, puedo sugerir esto:
from functools import reduce
def fun(df , var, val):
_sub = reduce(
lambda x, y: x & (df[y] == val),
var,
pd.Series([True]*df.shape[0])
)
return df[_sub]
Esto funcionará con cualquier número de variables de columna de entrada. Espero que esto sirva de inspiración para sus operaciones más complicadas que tiene la intención de hacer.
En este caso, está accediendo a var[2]
pero una lista de 2 elementos en Python tiene los elementos 0 y 1. El elemento 2 no existe y, por lo tanto, el acceso está fuera de rango.
Preguntas relacionadas
Nuevas preguntas
python
Python es un lenguaje de programación multipropósito, de tipificación dinámica y de múltiples paradigmas. Está diseñado para ser rápido de aprender, comprender y usar, y hacer cumplir una sintaxis limpia y uniforme. Tenga en cuenta que Python 2 está oficialmente fuera de soporte a partir del 01-01-2020. Aún así, para preguntas de Python específicas de la versión, agregue la etiqueta [python-2.7] o [python-3.x]. Cuando utilice una variante de Python (por ejemplo, Jython, PyPy) o una biblioteca (por ejemplo, Pandas y NumPy), inclúyala en las etiquetas.