es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Pandas: Buscar recursivamente columnas padres e hijas para obtener todos los hijos.

Tengo un conjunto de datos (muy grande) en el que no sé cuántos “niveles” o profundidad tiene la relación entre el padre y el hijo. Lo que sí sé es que necesito:

  1. Para cada elemento que buscamos, encontrar el conjunto de valores encontrados en la columna “related”: related_child = df.loc[df['source'] == 'A']['related'].values
  2. Para cada valor devuelto en el paso 1, asumir que son padres y buscar sus hijos en los valores de “related”: df.loc[df['source'].isin(related_child)]['related'].values
  3. Repetir el paso 2 hasta que no se encuentren más hijos, asumiendo cada vez que los valores encontrados en “related” deben ser ellos mismos padres y tener hijos.

Estoy teniendo problemas con el manejo de la unicidad, de modo que no siga devolviendo los mismos resultados, sino que entienda que ya encontró ese hijo y no siga buscándolo exhaustivamente de manera lógica.

# Ejemplo de juguete del conjunto de datos
df = pd.DataFrame({'source': ['A', 'A', 'A', 'A', 'B', 'B'],
                   'related': ['C', 'D', 'E', 'B', 'F', 'A']
                   })

¿Cómo puedo recorrer rápidamente mi marco de datos mientras registro todos los hijos encontrados?
Tags:  , ,

Answer

  1. Avatar for davy.ai

    Una forma de llevar un registro de los hijos ya encontrados es usar un conjunto (set) para almacenarlos. Antes de buscar los hijos de un padre, podemos verificar si ya hemos buscado ese padre revisando si está en el conjunto. Si está en el conjunto, podemos omitir ese padre y pasar al siguiente. Si no está en el conjunto, podemos agregarlo al conjunto antes de buscar sus hijos.

    Aquí hay una implementación de ejemplo:

    def find_related(df, start):
        found_children = set()
        parents = [start]
        while parents:
            children = []
            for parent in parents:
                if parent in found_children:
                    continue
                found_children.add(parent)
                related_child = df.loc[df['source'] == parent]['related'].values
                children.extend(related_child)
            parents = children
        return found_children
    

    Esta función recibe un marco de datos (dataframe) df y un nodo padre inicial start. Inicializa un conjunto vacío llamado found_children para llevar un registro de los nodos que ya hemos buscado. También inicializa una lista con el nodo padre inicial.

    Luego, entramos en un bucle while que continúa mientras haya padres que buscar. Dentro del bucle, inicializamos una lista vacía llamada children para almacenar los hijos que encontramos. Luego, recorremos cada padre en la lista parents. Si ya hemos encontrado ese padre antes, lo omitimos usando la palabra clave continue. Si no lo hemos encontrado antes, lo agregamos al conjunto found_children y buscamos sus hijos usando el código del paso 1. Luego, extendemos la lista children con los nuevos hijos que encontramos.

    Después de buscar todos los padres en un nivel dado, actualizamos la lista parents para que sea la lista children que acabamos de encontrar. Repetimos este proceso hasta que no haya más hijos que encontrar.

    Finalmente, la función devuelve el conjunto found_children, que contiene todos los hijos que encontramos.

    Para usar esta función con el marco de datos de ejemplo, podemos llamar a find_related(df, 'B') para encontrar todos los hijos relacionados con el nodo 'B'. La salida debería ser {'A', 'C', 'D', 'E', 'F'}.

Comments are closed.