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:
- Para cada elemento que buscamos, encontrar el conjunto de valores encontrados en la columna “related”:
related_child = df.loc[df['source'] == 'A']['related'].values
- 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
- 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?
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:
Esta función recibe un marco de datos (dataframe)
df
y un nodo padre inicialstart
. Inicializa un conjunto vacío llamadofound_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 listaparents
. Si ya hemos encontrado ese padre antes, lo omitimos usando la palabra clavecontinue
. Si no lo hemos encontrado antes, lo agregamos al conjuntofound_children
y buscamos sus hijos usando el código del paso 1. Luego, extendemos la listachildren
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 listachildren
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'}
.