networkx与PyG计算度数degree时需避免的坑:自环selfloop和多重边

2023-10-29 10:10

本文主要是介绍networkx与PyG计算度数degree时需避免的坑:自环selfloop和多重边,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

networkx与PyG计算度数degree时需避免的坑:自环selfloop和多重边

  • networkx
    • 有向图的self-loop
    • 无向图self-loop
    • 多重边
  • pytorch geometric

近日需要统计图的基本性质,在使用 nxPyG自带的度数计算时,发现他们的底层逻辑是不同的,因此计算结果在一些情况下也会不同。这里做个简单的小结,也避免自己今后踩坑。

先上结论:

  • networkx在计算度数的时候,自环selfloop部分会被计算为2,多重边只计算一条。
  • PyG中度数计算不分方向,只和传入index中每个节点出现的次数有关。
    • 使用PyG中的to_undirected将有向图转化为无向图后,自环边只有一条,因此自环度数为1
    • 多重边的度数为相应为n

下面分别看一下具体的实例。

networkx

有向图的self-loop

import networkx as nx
DG = nx.DiGraph()
DG.add_edges_from([[0, 0], [0, 1], [1, 2]])
nx.draw(DG, with_labels=True)

在这里插入图片描述
分别计算degree, out_degreein_degree

DG.degree(DG.nodes())
>>> DiDegreeView({0: 3, 1: 2, 2: 1}) #节点0的度数为3,因为自环的度数是2
DG.out_degree(DG.nodes())
>>> OutDegreeView({0: 2, 1: 1, 2: 0}) #节点0的出度为2,因为自环提供了出度1
DG.in_degree(DG.nodes())
>>> InDegreeView({0: 1, 1: 1, 2: 1}) #节点0的入度为1,因为自环提供了入度1

我们可以看到节点0degree, out_degreein_degree分别为3, 2, 1,这是因为在计算度数的时候,有向图中selfloop提供了2的度数。同样都是自己指向自己,但一次是自己指向了跟自己相同的邻居,一次是跟自己相同的邻居指向了自己。其中前者是出度,后者是入度。

无向图self-loop

import networkx as nx
G = nx.Graph()
G.add_edges_from([[0, 0], [0, 1], [1, 2]])
nx.draw(G, with_labels=True)

在这里插入图片描述

G.degree(G.nodes())
DegreeView({0: 3, 1: 2, 2: 1})

其中节点0的度数仍然为3。另外对于无向图,in_degreeout_degree方法不再适用。

多重边

import networkx as nx
DG = nx.DiGraph()
DG.add_edges_from([[0, 1], [0,1], [1, 2]])
nx.draw(DG, with_labels=True)

在这里插入图片描述

DG.out_degree(DG.nodes())
>>> OutDegreeView({0: 1, 1: 1, 2: 0})

可以看到尽管有两条(0,1)边,在计算度数的时候,只会被算作一条。这是因为nx内部存储是以字典形式存储信息的,多重边对应的键是一样的,因此后来传入的信息会覆盖前面的信息。

pytorch geometric

PyG的度数计算是利用torchscatter,所以是不分方向的,只看你传进去什么样的index。下面给大家举个例子:

from torch_geometric.utils import degree
import torchedge_index = torch.tensor([[0, 0], [0, 1], [1, 2]]).T.contiguous() #传入和nx例子中相同的边
edge_index
>>> 
tensor([[0, 0, 1],[0, 1, 2]])degree(edge_index[0])
>>> tensor([2., 1.])  #传入edge_index[0]计算出度,因为节点2没有出度,所以这里出度的shape只有(2,)degree(edge_index[0], num_nodes=3)
>>> tensor([2., 1., 0.]) #指定节点个数,避免维度不同degree(edge_index[1])
>>> degree(edge_index[1]) #传入edge_index[1]计算入度

PyGedge_index[0]source,所以对degree函数传入edge_index[0]计算出度。计算的逻辑就是统计index中每个节点出现的次数。如果有节点没有出度且节点的id在尾部,可以传入节点的个数,避免返回的结果出现缺失。同理传入edge_index[1]计算入度。

如果需要计算度数,可以先对有向的edge_index做无向处理。

from torch_geometric.utils import to_undirected
edge_index = to_undirected(edge_index)
edge_index
>>> tensor([[0, 0, 1, 1, 2],    #节点0的自环边只出现一次[0, 1, 0, 2, 1]])degree(edge_index[0])
>>> tensor([2., 2., 1.])

可以看出来,to_undirected并不会重复自环边,所以后期计算自环度数时为1

因为计算的degree只和传入的index有关,所以重复边会被重复统计。

from torch_geometric.utils import degree
import torchedge_index = torch.tensor([[0, 1], [0, 1], [1, 2]]).T.contiguous() #传入和上个例子中相同的边
edge_index
>>> tensor([[0, 0, 1],[1, 1, 2]])degree(edge_index[0])
>>> tensor([2., 1.])

这篇关于networkx与PyG计算度数degree时需避免的坑:自环selfloop和多重边的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/299948

相关文章

Python并行处理实战之如何使用ProcessPoolExecutor加速计算

《Python并行处理实战之如何使用ProcessPoolExecutor加速计算》Python提供了多种并行处理的方式,其中concurrent.futures模块的ProcessPoolExecu... 目录简介完整代码示例代码解释1. 导入必要的模块2. 定义处理函数3. 主函数4. 生成数字列表5.

正则表达式r前缀使用指南及如何避免常见错误

《正则表达式r前缀使用指南及如何避免常见错误》正则表达式是处理字符串的强大工具,但它常常伴随着转义字符的复杂性,本文将简洁地讲解r的作用、基本原理,以及如何在实际代码中避免常见错误,感兴趣的朋友一... 目录1. 字符串的双重翻译困境2. 为什么需要 r?3. 常见错误和正确用法4. Unicode 转换的

Java计算经纬度距离的示例代码

《Java计算经纬度距离的示例代码》在Java中计算两个经纬度之间的距离,可以使用多种方法(代码示例均返回米为单位),文中整理了常用的5种方法,感兴趣的小伙伴可以了解一下... 目录1. Haversine公式(中等精度,推荐通用场景)2. 球面余弦定理(简单但精度较低)3. Vincenty公式(高精度,

Python多重继承慎用的地方

《Python多重继承慎用的地方》多重继承也可能导致一些问题,本文主要介绍了Python多重继承慎用的地方,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录前言多重继承要慎用Mixin模式最后前言在python中,多重继承是一种强大的功能,它允许一个

windows和Linux使用命令行计算文件的MD5值

《windows和Linux使用命令行计算文件的MD5值》在Windows和Linux系统中,您可以使用命令行(终端或命令提示符)来计算文件的MD5值,文章介绍了在Windows和Linux/macO... 目录在Windows上:在linux或MACOS上:总结在Windows上:可以使用certuti

Java Optional避免空指针异常的实现

《JavaOptional避免空指针异常的实现》空指针异常一直是困扰开发者的常见问题之一,本文主要介绍了JavaOptional避免空指针异常的实现,帮助开发者编写更健壮、可读性更高的代码,减少因... 目录一、Optional 概述二、Optional 的创建三、Optional 的常用方法四、Optio

Python如何计算两个不同类型列表的相似度

《Python如何计算两个不同类型列表的相似度》在编程中,经常需要比较两个列表的相似度,尤其是当这两个列表包含不同类型的元素时,下面小编就来讲讲如何使用Python计算两个不同类型列表的相似度吧... 目录摘要引言数字类型相似度欧几里得距离曼哈顿距离字符串类型相似度Levenshtein距离Jaccard相

C#多线程编程中导致死锁的常见陷阱和避免方法

《C#多线程编程中导致死锁的常见陷阱和避免方法》在C#多线程编程中,死锁(Deadlock)是一种常见的、令人头疼的错误,死锁通常发生在多个线程试图获取多个资源的锁时,导致相互等待对方释放资源,最终形... 目录引言1. 什么是死锁?死锁的典型条件:2. 导致死锁的常见原因2.1 锁的顺序问题错误示例:不同

Pandas中多重索引技巧的实现

《Pandas中多重索引技巧的实现》Pandas中的多重索引功能强大,适用于处理多维数据,本文就来介绍一下多重索引技巧,具有一定的参考价值,感兴趣的可以了解一下... 目录1.多重索引概述2.多重索引的基本操作2.1 选择和切片多重索引2.2 交换层级与重设索引3.多重索引的高级操作3.1 多重索引的分组聚

使用C#代码计算数学表达式实例

《使用C#代码计算数学表达式实例》这段文字主要讲述了如何使用C#语言来计算数学表达式,该程序通过使用Dictionary保存变量,定义了运算符优先级,并实现了EvaluateExpression方法来... 目录C#代码计算数学表达式该方法很长,因此我将分段描述下面的代码片段显示了下一步以下代码显示该方法如