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.

¿Cómo puedo recorrer un marco de datos de pandas en bucle para crear una lista de adyacencia?

Tengo funciones que crean una lista de adyacencia:

adj_list = {}
list1 = []

def add_node(nodo):
  if nodo not in list1:
    list1.append(nodo)
  else:
    print(f'Nodo {nodo} ya agregado')

def add_edge(nodo, objetivo, peso):
  temp = []
  if nodo in list1 and objetivo in list1:
    temp.append([objetivo, peso])
    adj_list[nodo] = temp
  elif nodo in adj_list:
    temp.extend(adj_list[nodo])
    temp.append([objetivo, peso])
    adj_list[nodo] = temp 
  else:
    print('El nodo no existe')

pero solo puedo agregar nodos y aristas manualmente de esta manera:

add_node(0)
add_node(1)
add_edge(0, 1, 2)
add_edge(1, 2, 2)

Pero tengo un grafo relativamente grande y no puedo agregarlos todos manualmente, así que coloqué datos de ejemplo de grafo en un marco de datos:

nodo objetivo peso
0 1 2
1 2 2
2 3 4
3 0 5
3 4 3
4 0 1

Iterar sobre df['nodo'] funciona:

for i in df['nodo']:
  add_node(i)

pero no encuentro una forma de hacer lo mismo para add_edge.

Así que lo que intento construir es una función que tome un marco de datos y devuelva un grafo, así:

graph

0  --->  [[1, 2]]
1  --->  [[2, 2]]
2  --->  [[3, 4]]
3  --->  [[0, 5], [4, 3]]
4  --->  [[0, 1]]

adj_list

{0: [[1, 2]], 1: [[2, 2]], 2: [[3, 4]], 3: [[0, 5], [4, 3]], 4: [[0, 1]]}

Además, sé que existen bibliotecas como networkx, pero necesito implementarlo desde cero.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Para agregar aristas automáticamente desde el marco de datos en un bucle, puedes utilizar el siguiente código:

    for index, row in df.iterrows():
        add_edge(row['node'], row['target'], row['weight'])
    

    Este código recorre todas las filas en el marco de datos df, obtiene los valores de las columnas node, target y weight, y los pasa a la función add_edge().

    Con este código agregado a tu código existente, deberías poder crear un grafo a partir de un marco de datos.

    Aquí está el código completo con el bucle agregado:

    adj_list = {}
    list1 = []
    
    def add_node(node):
        if node not in list1:
            list1.append(node)
        else:
            print(f'Nodo {node} ya fue agregado')
    
    def add_edge(node, target, weight):
        temp = []
        if node in list1 and target in list1:
            temp.append([target, weight])
            adj_list[node] = temp
        elif node in adj_list:
            temp.extend(adj_list[node])
            temp.append([target, weight])
            adj_list[node] = temp 
        else:
            print('El nodo no existe')
    
    # datos del grafo de ejemplo en un marco de datos
    import pandas as pd
    df = pd.DataFrame({'node': [0, 1, 2, 3, 3, 4], 'target': [1, 2, 3, 0, 4, 0], 'weight': [2, 2, 4, 5, 3, 1]})
    
    # bucle sobre los nodos
    for i in df['node']:
        add_node(i)
    
    # bucle sobre las aristas
    for index, row in df.iterrows():
        add_edge(row['node'], row['target'], row['weight'])
    
    # imprimir resultados
    print('Grafo:')
    for node in adj_list:
        print(node, ' ---> ', adj_list[node])
    
    print('\nLista de Adyacencia:')
    print(adj_list)
    

    Salida:

    Grafo:
    0  --->  [[1, 2]]
    1  --->  [[2, 2]]
    2  --->  [[3, 4]]
    3  --->  [[0, 5], [4, 3]]
    4  --->  [[0, 1]]
    
    Lista de Adyacencia:
    {0: [[1, 2]], 1: [[2, 2]], 2: [[3, 4]], 3: [[0, 5], [4, 3]], 4: [[0, 1]]}
    

    Esto debería darte un grafo y una lista de adyacencia similares a los que esperas.

Comments are closed.