Un guide complet sur le traitement des données graphiques en Python, des listes de bords bruts aux matrices de contiguïté

Cet article est partagé par la communauté Huawei Cloud « Un guide complet pour implémenter le traitement des données graphiques en Python, de la liste de contours d'origine à la matrice de contiguïté » par Lemony Hug.

En théorie des graphes et en analyse de réseaux, un graphe est une structure de données très importante composée de nœuds (ou sommets) et des arêtes reliant ces nœuds. En Python, nous pouvons représenter un graphique à l'aide d'une matrice de contiguïté, où les lignes et les colonnes de la matrice représentent des nœuds, et les valeurs de la matrice représentent s'il y a des arêtes entre les nœuds.

Liste des bords d'origine

Supposons que nous ayons une liste d'arêtes primitives où chaque élément représente une arête, par exemple :

bords = [(0, 1), (0, 2), (1, 2), (2, 3)]

Dans cet exemple, chaque tuple représente l'existence d'un bord entre le nœud et le nœud . (a, b)  a  b 

Convertir en matrice de contiguïté

Nous devons d’abord déterminer le nombre de nœuds dans le graphique, puis créer une matrice nulle de taille correspondante. Ensuite, nous parcourons la liste d'arêtes d'origine et définissons l'élément de matrice correspondant sur 1 en fonction des deux nœuds de chaque arête. La matrice finale obtenue est la matrice de contiguïté dont nous avons besoin.

Voyons comment implémenter ce processus dans le code Python :

def edge_to_adjacency_matrix(edges) :
    # Trouver le nombre de nœuds dans le graphique
    max_node = max(max(edge) pour le bord dans les bords) + 1
    
    #Créer une matrice zéro
    adjacency_matrix = [[0] * max_node pour _ dans la plage (max_node)]
    
    # Parcourez la liste de bords d'origine et mettez à jour la matrice de contiguïté
    pour bord dans bords :
        adjacency_matrix[edge[0]][edge[1]] = 1
        adjacency_matrix[edge[1]][edge[0]] = 1 # S'il s'agit d'un graphe non orienté, les arêtes sont bidirectionnelles
    
    retourner la matrice_de contiguïté

# test
bords = [(0, 1), (0, 2), (1, 2), (2, 3)]
adjacency_matrix = edge_to_adjacency_matrix(bords)
pour la ligne dans adjacency_matrix :
    imprimer (ligne)

Dans ce code, edges_to_adjacency_matrix la fonction accepte la liste d'arêtes d'origine comme argument et renvoie la matrice de contiguïté correspondante. Nous avons ensuite effectué le test sur la liste d'arêtes donnée et généré la matrice de contiguïté résultante.

Développer et optimiser

Bien que le code ci-dessus puisse compléter la conversion de la liste de bords d'origine en matrice de contiguïté, certaines extensions et optimisations peuvent être nécessaires dans des applications pratiques.

  1. Traitement des graphes orientés et non orientés : Le code actuel gère par défaut les graphes non orientés. S'il s'agit d'un graphe orienté, le code doit être modifié en fonction des besoins spécifiques et la relation d'adjacence n'est définie que dans un sens.

  2. Gérer les poids : Parfois, un avantage n'est pas seulement une relation entre l'existence ou l'absence, mais peut aussi avoir un poids. Code modifié pour prendre en charge les graphiques pondérés.

  3. Utiliser des matrices clairsemées : pour les grands graphiques, les matrices de contiguïté peuvent occuper beaucoup de mémoire. Pensez à utiliser des matrices clairsemées pour économiser de l'espace mémoire.

  4. Optimisation des performances : pour les listes de bords à grande échelle, les performances du code doivent être prises en compte. Vous pouvez essayer d'utiliser des structures de données ou des algorithmes plus efficaces pour mettre en œuvre le processus de conversion.

Voici quelques exemples d’optimisations de votre code :

importer numpy en tant que np

defedges_to_adjacency_matrix(edges,direct=False) :
    max_node = max(max(edge) pour le bord dans les bords) + 1
    adjacency_matrix = np.zeros((max_node, max_node))
    pour bord dans bords :
        si demandé :
            adjacency_matrix[edge[0]][edge[1]] = 1
        autre:
            adjacency_matrix[edge[0]][edge[1]] = 1
            adjacency_matrix[edge[1]][edge[0]] = 1
    retourner la matrice_de contiguïté

# test
bords = [(0, 1), (0, 2), (1, 2), (2, 3)]
adjacency_matrix = edge_to_adjacency_matrix(bords)
print("Matrice de contiguïté du graphe non orienté :")
print (matrice_de contiguïté)

bords_dirigés = [(0, 1), (0, 2), (1, 2), (2, 3)]
directed_adjacency_matrix =edges_to_adjacency_matrix(directed_edges,direct=True)
print("\nMatrice de contiguïté du graphe orienté :")
print(directed_adjacency_matrix)

Dans le code optimisé, nous utilisons la bibliothèque NumPy pour créer et manipuler des matrices, ce qui peut améliorer les performances et la lisibilité du code. Dans le même temps, nous avons ajouté un paramètre pour indiquer le type de graphique pour prendre en charge la conversion de graphiques orientés et non orientés. directed 

Optimiser l'empreinte mémoire à l'aide de matrices clairsemées

Lorsqu'il s'agit de grands graphiques, la matrice de contiguïté peut devenir très clairsemée, la plupart de ses éléments étant des zéros. Pour optimiser l'utilisation de la mémoire, une matrice clairsemée peut être utilisée pour représenter les relations de contiguïté.

Il existe une variété de bibliothèques en Python capables de gérer des matrices clairsemées, parmi lesquelles la bibliothèque Scipy fournit diverses opérations et algorithmes pour les matrices clairsemées. Voyons comment optimiser votre code à l'aide de matrices clairsemées dans Scipy :

importer numpy en tant que np
depuis scipy.sparse importer lil_matrix

defedges_to_adjacency_matrix(edges,direct=False) :
    max_node = max(max(edge) pour le bord dans les bords) + 1
    adjacency_matrix = lil_matrix((max_node, max_node), dtype=np.int8)
    pour bord dans bords :
        si demandé :
            matrice_de contiguïté[bord[0], bord[1]] = 1
        autre:
            matrice_de contiguïté[bord[0], bord[1]] = 1
            adjacency_matrix[edge[1], edge[0]] = 1
    retourner la matrice_de contiguïté

# test
bords = [(0, 1), (0, 2), (1, 2), (2, 3)]
adjacency_matrix = edge_to_adjacency_matrix(bords)
print("Matrice de contiguïté du graphe non orienté :")
print(adjacency_matrix.toarray())

bords_dirigés = [(0, 1), (0, 2), (1, 2), (2, 3)]
directed_adjacency_matrix =edges_to_adjacency_matrix(directed_edges,direct=True)
print("\nMatrice de contiguïté du graphe orienté :")
print(directed_adjacency_matrix.toarray())

Dans cette version du code, nous utilisons pour créer une matrice clairsemée. Il peut gérer efficacement de grandes matrices clairsemées et ne stocke que des éléments non nuls, économisant ainsi de la mémoire. scipy.sparse.lil_matrix 

Grâce à cette optimisation, nous pouvons traiter des données graphiques plus volumineuses sans provoquer de dégradation des performances ou de problèmes de mémoire insuffisante dus à une utilisation excessive de la mémoire.

Traiter les listes de bords pondérées

Dans certains cas, les bords du graphique représentent non seulement les relations de connexion entre les nœuds, mais peuvent également contenir des informations de poids. Par exemple, dans un réseau de transport, les bords peuvent représenter des routes et les poids peuvent représenter la longueur ou le temps de trajet d'une route.

Voyons comment nous pouvons modifier le code pour prendre en charge les listes de bords pondérées :

importer numpy en tant que np
depuis scipy.sparse importer lil_matrix

def edge_to_adjacency_matrix(edges, direction=False, pondéré=False) :
    max_node = max(max(edge[0], edge[1]) pour le bord dans les bords) + 1
    adjacency_matrix = lil_matrix((max_node, max_node), dtype=np.float32)
    pour bord dans bords :
        si demandé :
            si pondéré :
                adjacency_matrix[edge[0], edge[1]] = edge[2]
            autre:
                matrice_de contiguïté[bord[0], bord[1]] = 1
        autre:
            si pondéré :
                adjacency_matrix[edge[0], edge[1]] = edge[2]
                adjacency_matrix[edge[1], edge[0]] = edge[2]
            autre:
                matrice_de contiguïté[bord[0], bord[1]] = 1
                adjacency_matrix[edge[1], edge[0]] = 1
    retourner la matrice_de contiguïté

# test
pondérés_edges = [(0, 1, 5), (0, 2, 3), (1, 2, 2), (2, 3, 7)]
Weighted_adjacency_matrix = Edges_to_adjacency_matrix (weighted_edges, pondéré = True)
print("Matrice de contiguïté pondérée :")
print(weighted_adjacency_matrix.toarray())

Dans cette version du code, nous avons ajouté un paramètre pour indiquer si le bord est pondéré. Si l'argument est , alors les informations de poids sont extraites de la liste des bords et enregistrées dans la matrice de contiguïté. Sinon, les valeurs de la matrice de contiguïté représentent toujours la présence ou l'absence du bord. weighted  weighted  True

Avec cette modification, nous pouvons traiter les données graphiques avec des informations de poids et conserver ces informations dans la matrice de contiguïté pour des analyses et des calculs ultérieurs.

Visualisation de graphiques

Lorsqu'il s'agit de données graphiques, la visualisation est un outil puissant qui peut nous aider à comprendre intuitivement la structure et les caractéristiques du graphique. Il existe de nombreuses bibliothèques en Python qui peuvent être utilisées pour visualiser des données graphiques, parmi lesquelles NetworkX est une bibliothèque couramment utilisée qui fournit des fonctions riches pour créer, manipuler et visualiser des graphiques.

Voyons comment utiliser NetworkX pour visualiser notre matrice de contiguïté générée :

importer networkx en tant que nx
importer matplotlib.pyplot en tant que plt

def visualize_adjacency_matrix(adjacency_matrix) :
    G = nx.from_numpy_matrix (adjacency_matrix)
    pos = nx.spring_layout(G) # Définir la position du nœud
    nx.draw(G, pos, with_labels=True, node_color='skyblue', node_size=500, font_size=10) # Mise à jour
    edge_labels = {(i, j): w['weight'] for i, j, w in G.edges(data=True)} # Obtenir les poids des bords
    nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels, font_size=10) # Dessiner les poids des bords
    plt.title("Visualisation graphique")
    plt.show()

# test
pondérés_edges = [(0, 1, 5), (0, 2, 3), (1, 2, 2), (2, 3, 7)]
Weighted_adjacency_matrix = Edges_to_adjacency_matrix (weighted_edges, pondéré = True)
print("Matrice de contiguïté pondérée :")
print(weighted_adjacency_matrix.toarray())

visualize_adjacency_matrix(weighted_adjacency_matrix.toarray())

Dans ce code, nous convertissons d'abord la matrice de contiguïté en un objet graphique à l'aide des fonctions de NetworkX. Utilisez ensuite la position du nœud défini et dessinez le graphique à l'aide de la fonction. Enfin, nous traçons les poids des bords à l'aide d'une fonction. from_numpy_matrix  spring_layout  draw  draw_networkx_edge_labels 

Grâce à la visualisation, nous pouvons voir clairement la structure du graphique et comprendre intuitivement les relations de connexion et les informations de poids entre les nœuds.

Convertir la matrice de contiguïté en liste de bords bruts

Dans le traitement des données graphiques, nous devons parfois reconvertir la matrice de contiguïté sous sa forme de liste de bords d'origine. Cela peut être utile dans certains algorithmes et applications, car certains algorithmes peuvent être mieux adaptés à l'utilisation de listes d'arêtes pour représenter le graphique.

Voyons comment écrire du code pour réaliser cette conversion :

importer numpy en tant que np

def adjacency_matrix_to_edges(adjacency_matrix) :
    bords = []
    pour moi dans la plage (adjacency_matrix.shape[0]):
        pour j dans la plage (adjacency_matrix.shape[1]) :
            si adjacency_matrix[i, j] != 0 :
                bords.append((i, j, adjacency_matrix[i, j]))
    bords de retour

# test
adjacency_matrix = np.array([[0, 1, 0, 0],
                              [1, 0, 1, 0],
                              [0, 1, 0, 1],
                              [0, 0, 1, 0]], dtype=np.float32)
print("Matrice de contiguïté originale :")
print (matrice_de contiguïté)

bords = adjacency_matrix_to_edges (adjacency_matrix)
print("\nListe des bords convertis :")
imprimer (bords)

Dans ce code, nous parcourons chaque élément de la matrice de contiguïté et si la valeur de l'élément est non nulle, nous le convertissons en une arête dans la liste d'arêtes. Pour les graphiques avec poids, nous enregistrons également les informations de poids dans la liste des bords.

Grâce à ce processus de conversion, nous pouvons convertir le graphique représenté par la matrice d'adjacence sous la forme d'une liste d'arêtes, facilitant ainsi la mise en œuvre et l'application de certains algorithmes.

Résumé et perspectives

Cet article présente comment utiliser Python pour convertir la liste de contours d'origine en une matrice de contiguïté et réalise une série d'extensions et d'optimisations pour répondre aux besoins de différents scénarios. Nous couvrons plusieurs aspects du traitement des données graphiques, du traitement des graphiques non orientés et orientés, des listes d'arêtes pondérées, à l'utilisation de matrices clairsemées pour optimiser l'utilisation de la mémoire, à la visualisation graphique et à la conversion de matrices de contiguïté en listes d'arêtes brutes.

Dans les applications pratiques, le traitement des données graphiques est un domaine très important et largement utilisé, impliquant l'analyse des réseaux, les réseaux sociaux, la planification des transports, la bioinformatique et bien d'autres domaines. Maîtriser les compétences en traitement des données graphiques peut nous aider à mieux comprendre et analyser des structures de données complexes pour résoudre des problèmes pratiques.

À l’avenir, à mesure que l’échelle et la complexité des données continueront d’augmenter, le domaine du traitement des données graphiques sera confronté à davantage de défis et d’opportunités. Nous pouvons nous attendre à ce que des outils et des algorithmes plus efficaces, flexibles et riches en fonctionnalités émergent pour répondre aux besoins et aux défis changeants. Dans le même temps, nous pouvons également continuer à apprendre et à explorer, améliorer constamment nos capacités et nos niveaux dans le domaine du traitement des données graphiques et contribuer davantage à la résolution de problèmes pratiques.

J'espère que cet article vous aidera à comprendre et à appliquer le traitement des données graphiques. Vous êtes également invités à approfondir et à explorer ce domaine et à contribuer au développement de la science et de l'ingénierie des données.

Cliquez pour suivre et découvrir les nouvelles technologies de Huawei Cloud dès que possible~

 

L'équipe de la Google Python Foundation a été licenciée. Google a confirmé les licenciements et les équipes impliquées dans Flutter, Dart et Python se sont précipitées vers la hot list de GitHub - Comment les langages et frameworks de programmation open source peuvent-ils être si mignons ? Xshell 8 ouvre le test bêta : prend en charge le protocole RDP et peut se connecter à distance à Windows 10/11 Lorsque les passagers se connectent au WiFi ferroviaire à grande vitesse , la « malédiction vieille de 35 ans » des codeurs chinois apparaît lorsqu'ils se connectent au haut débit. rail WiFi. Le premier outil de recherche IA à support à long terme de MySQL version 8.4 Perplexica : Entièrement open source et gratuit, une alternative open source à Perplexity. Les dirigeants de Huawei évaluent la valeur de l'open source Hongmeng : il possède toujours son propre système d'exploitation malgré une suppression continue. par des pays étrangers. La société allemande de logiciels automobiles Elektrobit a ouvert une solution de système d'exploitation automobile basée sur Ubuntu.
{{o.name}}
{{m.nom}}

Je suppose que tu aimes

Origine my.oschina.net/u/4526289/blog/11065906
conseillé
Classement