Nombres y valores en Python

Había venido elaborando una clase de Python que implementaría la elaboración de un reporte a partir de un dataframe de Pandas. el constructor de la clase iniciaba con:

    def __init__(self, dataframe, pipe_id=None):
        # Filter by pipeline_run_id if provided
        if pipe_id is not None:
            self.df = dataframe[dataframe['pipeline_run_id'] == pipe_id].copy()
            self.df.reset_index(drop=True, inplace=True)
        else:
            self.df = dataframe.copy()  # Store a copy of the original DataFrame
         ...

y en alguna parte, a través de otro método, tenía:

        ...
        # Expand the 'eval' column if it exists and add those columns to the DataFrame
        if 'eval' in self.df.columns:
            eval_df = pd.json_normalize(self.df['eval'])
            self.df = pd.concat([self.df.drop('eval', axis=1), eval_df], axis=1)
            del eval_df
        ...

donde a ese dataframe lo enriquezco convirtiendo una columna que contiene un JSON en cada registro a columnas. La implementación de la clase disparó algunos errores en el pipeline donde debía correr (que ni idea tuve del porqué, ni de su solución) y decidí transformar la clase a simples funciones. Entonces, lo que era un método sin parámetros pasó a una función declarada:

def prepare(df:pd.DataFrame):
        ...
        if 'eval' in df.columns:
            eval_df = pd.json_normalize(df['eval'])
            df = pd.concat([df.drop('eval', axis=1), eval_df], axis=1)
            del eval_df

Según uno aprende, en estos casos el paso del dataframe a la función es por referencia y, equivocadamente, pensé que dicha referencia era permanente, de manera que la concatenación del dataframe original (el recibido como argumento) con uno temporal (donde tenía la expansión resultante del JSON), y asignando el resultado al nombre del parámetro, afectaría al dataframe original. Sí, lo sé… error de novato, ahora que lo escribo veo la tontería asumida.

El concat() termina creando un nuevo objeto, creado en el contexto (scope) de la función y que deja de existir al terminar el llamado a ésta, por lo que el dataframe original se queda hasta donde haya sido alterado (si es el caso) previamente a la asignación del concat() a df.

Referencias

  1. Ned Batchelder, «Facts and myths about Python names and values«, blog. Updated: 20145.01.26; visited: 2024.12.06. URL: https://nedbatchelder.com/text/names.html

Deja un comentario

Este sitio utiliza Akismet para reducir el spam. Conoce cómo se procesan los datos de tus comentarios.