前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >networkx中的对象的使用

networkx中的对象的使用

原创
作者头像
从不摸鱼的van
修改2023-10-10 14:52:00
1960
修改2023-10-10 14:52:00
举报
文章被收录于专栏:杂七杂八

在开发过程中,nx的节点是我自己定义的字典,由于业务需求,我需要将其抽象成一个对象,下面来讲讲我的具体操作流程。


1.创建dataclasses类

`dataclasses` 是 Python 中的一个模块,用于简化创建不可变数据类的过程,自动添加特殊方法(如 `__init__`、`__repr__`、`__eq__` 等),减少样板代码,使数据类的定义更加简洁。由于我建立的图网络不需要经常更改数据,所以使用它简化我的开发流程是再好不过了:

代码语言:python
代码运行次数:0
复制
import dataclasses
@dataclasses.dataclass
class Node:
    perma_id: int
    value: int
    color: str

同时为了使其散列化,重写Node类的__hash__方法和__eq__方法:

__hash__方法将perma_id作为node对象的散列值,由于是perma_id,而且python会动态增加散列表的长度所以基本不会发生散列冲突,__eq__函数将两个对象是否相同的依据改为它们的perma_id是否相同,因为两个对象如果逻辑上相同,那么它们的哈希值一定相同。

代码语言:python
代码运行次数:0
复制
    def __hash__(self):
        return self.perma_id

    def __eq__(self, other):
        if isinstance(other, Node):
            return self.perma_id == other.perma_id
        return False

现在我们试着实例化一个node对象:

代码语言:python
代码运行次数:0
复制
node = Node(1, 2, 'red')

output:

代码语言:python
代码运行次数:0
复制
Node(perma_id=1, value=2, color='red')

现在我们尝试多加几个点,并将它们放在一张无向图里面,然后输出:

代码语言:python
代码运行次数:0
复制
import networkx as nx
node1 = Node(1, 18, 'red')
node2 = Node(2, 24, 'blue')
node3 = Node(3, 31, 'green')
node4 = Node(4, 4, 'yellow')
node5 = Node(5, 53, 'purple')
graph = nx.Graph()
graph.add_edge(node1, node2)
graph.add_edge(node1, node3)
graph.add_edge(node1, node4)
graph.add_edge(node1, node5)
print(graph)
for n, nbrs in graph.adj.items():
    for nbr, eattr in nbrs.items():
        print(n, nbr)

output:

代码语言:python
代码运行次数:0
复制
Graph with 5 nodes and 4 edges
Node(perma_id=1, value=18, color='red') Node(perma_id=2, value=24, color='blue')
Node(perma_id=1, value=18, color='red') Node(perma_id=3, value=31, color='green')
Node(perma_id=1, value=18, color='red') Node(perma_id=4, value=4, color='yellow')
Node(perma_id=1, value=18, color='red') Node(perma_id=5, value=53, color='purple')
Node(perma_id=2, value=24, color='blue') Node(perma_id=1, value=18, color='red')
Node(perma_id=3, value=31, color='green') Node(perma_id=1, value=18, color='red')
Node(perma_id=4, value=4, color='yellow') Node(perma_id=1, value=18, color='red')

2.查询对象信息

此时一切美好,但是如果我们想使用perma_id查询一个节点的具体信息呢,我们该怎么做?

这个时候我有两种解决方法:

1.在创建节点时使用一个字典将perma_id和节点对象关联起来,查询信息时就直接将perma_id映射到节点对象,然后再去查询,字典查询的复杂度永远为O(1),但是会有额外的字典存储的空间开销。

如我想查询perma_id为1的节点的相关边的信息我可以这样写代码:

代码语言:python
代码运行次数:0
复制
node_list = [node1, node2, node3, node4, node5]
node_map = {node.perma_id: node for node in node_list}
edges = graph.edges(node_map[1])
for edge in edges:
    print(edge)

output:

代码语言:python
代码运行次数:0
复制
(Node(perma_id=1, value=18, color='red'), Node(perma_id=2, value=24, color='blue'))
(Node(perma_id=1, value=18, color='red'), Node(perma_id=3, value=31, color='green'))
(Node(perma_id=1, value=18, color='red'), Node(perma_id=4, value=4, color='yellow'))
(Node(perma_id=1, value=18, color='red'), Node(perma_id=5, value=53, color='purple'))

2.我们也可以使用python自带的filter方法:

代码语言:python
代码运行次数:0
复制
def filter_nodes(edge,perma_id):
    return edge[0].perma_id == perma_id or edge[1].perma_id == perma_id
edges = graph.edges()
edges = list(filter(lambda edge: filter_nodes(edge, 1), edges))
for edge in edges:
    print(edge)

output:

代码语言:python
代码运行次数:0
复制
(Node(perma_id=1, value=18, color='red'), Node(perma_id=2, value=24, color='blue'))
(Node(perma_id=1, value=18, color='red'), Node(perma_id=3, value=31, color='green'))
(Node(perma_id=1, value=18, color='red'), Node(perma_id=4, value=4, color='yellow'))
(Node(perma_id=1, value=18, color='red'), Node(perma_id=5, value=53, color='purple'))

由于fiter方法需要遍历整个可迭代对象,所以在大规模数据场景下,使用filter会带来额外的查询时间开销,所以方法的选择还是要看具体的应用场景,我选择了使用字典映射的方法,因为我的node节点具体业务中也才不过几千个而已。

同时,如果使用的是字典类型的数据,也可以使用映射或者filter的方法去获取字典的详细数据,也可以将字典映射存储到数据库中,或者将节点和边存储到数据库中,而不是存储整个图结构。也可以使用专门的图数据库进行复杂网络的研究,但是它们往往在个人开发中的显得比较臃肿,小型项目里面又显得成本比较昂贵,所以nx不失为一个优雅的选择。

当然,各位看官大大们如果有更好的方法也欢迎交流学习。

我正在参与2023腾讯技术创作特训营第二期有奖征文,瓜分万元奖池和键盘手表

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.创建dataclasses类
  • 2.查询对象信息
相关产品与服务
图数据库 KonisGraph
图数据库 KonisGraph(TencentDB for KonisGraph)是一种云端图数据库服务,基于腾讯在海量图数据上的实践经验,提供一站式海量图数据存储、管理、实时查询、计算、可视化分析能力;KonisGraph 支持属性图模型和 TinkerPop Gremlin 查询语言,能够帮助用户快速完成对图数据的建模、查询和可视化分析。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档