1
\$\begingroup\$

I'm working on a code snippet that generates a network graph.

def create_network(df, node, column_edge, column_edge1=None, column_edge2=None):

    #  select columns, remove NaN
    df_edge1 = df[[node, column_edge]].dropna(subset=[column_edge]).drop_duplicates()

    # To create connections between "node" who have the same "edge",
    # join data with itself on the "node" column.
    df_edge1 = df_edge1.merge(
                              df_edge1[[node, column_edge]].rename(columns={node:node+"_2"}), 
                              on=column_edge
                              )

    # By joining the data with itself, node will have a connection with themselves.
    # Remove self connections, to keep only connected nodes which are different.
    edge1 = df_edge1[~(df_edge1[node]==df_edge1[node+"_2"])].dropna()[[node, node +"_2", column_edge]]
        
    # To avoid counting twice the connections (person 1 connected to person 2 and person 2 connected to person 1)
    # we force the first ID to be "lower" then ID_2
    edge1.drop(edge1.loc[edge1[node+"_2"]<edge1[node]].index.tolist(), inplace=True)

    G = nx.from_pandas_edgelist(df=edge1, source=node, target=node + '_2', edge_attr=column_edge)

    G.add_nodes_from(nodes_for_adding=df[node].tolist())


    if column_edge1:


        df_edge2 = df[[node, column_edge1]].dropna(subset=[column_edge1]).drop_duplicates()

        df_edge2 = df_edge2.merge(
            df_edge2[[node, column_edge1]].rename(columns={node:node+"_2"}), 
            on=column_edge1
        )

        edge2 = df_edge2[~(df_edge2[node]==df_edge2[node+"_2"])].dropna()[[node, node+"_2", column_edge1]]

        edge2.drop(edge2.loc[edge2[node+"_2"]<edge2[node]].index.tolist(), inplace=True)

        # Create the connections in the graph
        links_attributes = {tuple(row[[node, node+"_2"]]): {column_edge1: row[column_edge1]} for i,row in edge2.iterrows()}

        # create the connection, without attribute.
        G.add_edges_from(links_attributes)
        # adds the attribute.
        nx.set_edge_attributes(G=G, values=links_attributes)


    if column_edge2:

        df_edge3 = df[[node, column_edge2]].dropna(subset=[column_edge2]).drop_duplicates()

        df_edge3 = df_edge3.merge(
                                  df_edge3[[node, column_edge2]].rename(columns={node:node+"_2"}), 
                                  on=column_edge2
                                  )


        edge3 = df_edge3[~(df_edge3[node]==df_edge3[node+"_2"])].dropna()[[node, node+"_2", column_edge2]]

        edge3.drop(edge3.loc[edge3[node+"_2"]<edge3[node]].index.tolist(), inplace=True)

        # Create the connections in the graph
        links_attributes2 = {tuple(row[[node, node+"_2"]]): {column_edge2: row[column_edge2]} for i,row in edge3.iterrows()}

        # create the connection, without attribute.
        G.add_edges_from(links_attributes2) 
        # adds the attribute.
        nx.set_edge_attributes(G=G, values=links_attributes2)
    
    return G

The above function takes dataframe, node, and one or more column edges and generates the graph using Networkx python package.

Is there a better / more elegant / more accurate way to do this?

\$\endgroup\$

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.