【Python-图结构准备】“pickled object“、 调整邻接矩阵使其对称、图加自环 图邻接矩阵归一化、稀疏邻接矩阵格式转换

本文主要是介绍【Python-图结构准备】“pickled object“、 调整邻接矩阵使其对称、图加自环 图邻接矩阵归一化、稀疏邻接矩阵格式转换,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  • 引言:python代码学习,本博客对python的"pickled object" (腌制对象,也叫序列化对象), 调整邻接矩阵使其对称图加自环 & 图邻接矩阵归一化稀疏邻接矩阵格式转换从代码实现的角度进行介绍。我们先引入一段代码,通过这段代码来解释相应的知识点。
with open('data/' + args.dataset + '_mean_' + args.diffusion_model + str(10*args.seed_rate) + '.SG', 'rb') as f:graph = pickle.load(f)adj, inverse_pairs = graph['adj'], graph['inverse_pairs']adj = adj + adj.T.multiply(adj.T > adj) - adj.multiply(adj.T > adj)
adj = normalize_adj(adj + sp.eye(adj.shape[0]))
adj = torch.Tensor(adj.toarray()).to_sparse()
  • 上述代码是什么意思呢?我们逐行来分析。

知识点一:pickled object

  • “pickled object”(腌制对象)是指一个已经被序列化(serialized)的对象。序列化是将对象的状态信息转换为可以存储或传输的形式的过程。在Python中,这个过程通常是通过pickle模块来完成的。

  • 当使用pickle模块的dump函数将一个对象序列化到一个文件或字节流中时,这个对象就被"pickled"(腌制)了。序列化后的数据可以被存储在文件中,通过网络传输,或者以其他方式保存,被"pickled"的数据可以被pickle模块的load函数重新加载,恢复成原始的对象。

  • 例如,如果你有一个复杂的Python对象,比如一个包含多个嵌套字典和列表的数据结构,你可以使用pickle将其序列化到一个文件中:

import pickle
# 创建一个复杂的数据结构
data = {'name': 'Alice','age': 30,'friends': ['Bob', 'Charlie'],'scores': {'math': 90, 'english': 85}
}
# 将数据结构序列化到一个文件中
with open('data.pkl', 'wb') as f:pickle.dump(data, f)
  • 之后,你可以使用pickle.load函数从文件中加载这个pickled对象,并恢复成原始的数据结构:
# 从文件中加载pickled对象
with open('data.pkl', 'rb') as f:loaded_data = pickle.load(f)
# 现在loaded_data包含了原始的数据结构
print(loaded_data)
  • 需要注意的是,pickle模块是Python特有的,它生成的序列化数据是依赖于Python的实现细节的,因此不能跨语言使用。此外,由于pickle可以重建任何Python对象,包括执行代码,因此它可能存在安全风险,不应该用于加载不受信任或未经身份验证的数据。

知识点二 调整邻接矩阵使其对称

  • 本文开头提到的代码中,adj, inverse_pairs = graph['adj'], graph['inverse_pairs'] 这行代码从名为graph的字典中提取了两个键值对,adj和inverse_pairs。adj通常代表图的邻接矩阵,而inverse_pairs则是一些额外的图信息。
  • adj = adj + adj.T.multiply(adj.T > adj) - adj.multiply(adj.T > adj)
    • adj.T 是矩阵 adj 的转置矩阵。
    • (adj.T > adj) 是一个布尔矩阵,其中每个元素是 adj.T 中的元素与 adj 中对应位置的元素比较的结果。如果 adj.T 中的元素大于 adj 中的对应元素,则该位置为 True,否则为 False。
    • adj.T.multiply(adj.T > adj) 是矩阵乘法,它将 adj.T 中的每个元素与其对应位置的布尔值相乘。如果布尔值为 True,则结果是 adj.T 中的元素;如果布尔值为 False,则结果是 0。
    • adj.multiply(adj.T > adj) 是同样的操作,但是这次是使用 adj 矩阵。
    • adj + adj.T.multiply(adj.T > adj) - adj.multiply(adj.T > adj) 将原始矩阵 adj 与步骤3的结果相加,然后减去步骤4的结果。
    • 最终,这行代码的结果是一个新的矩阵,其中每个元素是原始矩阵 adj 中的元素,如果 adj.T 中的对应元素大于 adj 中的元素,则该元素被替换为 adj.T 中的对应元素;否则,该元素保持不变。换句话说,这行代码将 adj 中的每个元素替换为 adj.T 中对应位置的元素,前提是 adj.T 中的元素大于 adj 中的元素。
    • 如果用数学表达式来描述这个操作,对于矩阵 adj 中的每个元素 a_ij,新的值 a’_ij 将是:a'_ij = a_ij + (a_ji - a_ij) * (a_ji > a_ij),其中 a_ji 是 adj 的转置矩阵中对应位置的元素。如果 a_ji > a_ij,则 a’_ij = a_ji;否则,a’_ij = a_ij。

知识点三 图加自环 & 图邻接矩阵归一化

  • adj = normalize_adj(adj + sp.eye(adj.shape[0])) 这行代码调用了一个名为normalize_adj的函数,该函数用于归一化邻接矩阵。在归一化之前,它先将单位矩阵(sp.eye(adj.shape[0]))加到adj上。单位矩阵的对角线元素都是1,非对角线元素都是0,这个操作是为了确保每个节点至少与自己相连(自环)。
  • 其中 normalize_adj函数为:
def normalize_adj(mx):"""Row-normalize sparse matrix"""rowsum = np.array(mx.sum(1))r_inv_sqrt = np.power(rowsum, -0.5).flatten()r_inv_sqrt[np.isinf(r_inv_sqrt)] = 0.r_mat_inv_sqrt = sp.diags(r_inv_sqrt)return mx.dot(r_mat_inv_sqrt).transpose().dot(r_mat_inv_sqrt)
  • rowsum = np.array(mx.sum(1)) :这行代码计算了输入矩阵 mx 的每行之和,并将结果存储在 rowsum 数组中。

  • r_inv_sqrt = np.power(rowsum, -0.5).flatten():这行代码计算了 rowsum 数组中每个元素的负二分之一次方,即求每个行和的平方根的倒数。这样做的目的是为了准备对矩阵进行归一化。flatten() 函数将结果展平为一维数组。

  • r_inv_sqrt[np.isinf(r_inv_sqrt)] = 0. :这行代码检查 r_inv_sqrt 数组中是否有无穷大的值(这可能是因为行和为0导致的),并将这些无穷大的值替换为0。

  • r_mat_inv_sqrt = sp.diags(r_inv_sqrt):这行代码使用 r_inv_sqrt 数组创建了一个对角稀疏矩阵 r_mat_inv_sqrt,其中对角线上的元素是 r_inv_sqrt 中的值。

  • return mx.dot(r_mat_inv_sqrt).transpose().dot(r_mat_inv_sqrt) :这行代码返回了归一化后的矩阵。首先,mx.dot(r_mat_inv_sqrt) 将原始矩阵 mx 与 r_mat_inv_sqrt 相乘,这实际上是对 mx 的每一列进行缩放,使得每行的和为1。然后,transpose() 函数将结果转置,接着再次与 r_mat_inv_sqrt 相乘。这个转置和再次相乘的操作确保了归一化后的矩阵是对称的,这在图数据处理中是常见的,因为邻接矩阵通常是对称的。

知识点四 稀疏矩阵格式转换

  • adj = torch.Tensor(adj.toarray()).to_sparse() 这行代码将归一化后的邻接矩阵从稀疏矩阵格式转换为密集矩阵格式(toarray()),然后将其转换为PyTorch张量(torch.Tensor)。最后,它将这个张量转换为稀疏张量(to_sparse())。稀疏张量是一种优化表示,用于存储大多数元素为0的矩阵,这样可以节省内存和计算资源。
    在这行代码中,toarray() 和 to_sparse() 是两个不同的操作,它们分别将稀疏矩阵转换为密集数组,然后再将密集数组转换回稀疏张量。下面是这两个操作的详细解释:

  • toarray() :这个方法用于将稀疏矩阵(通常是 SciPy 的稀疏矩阵格式,如 scipy.sparse.csr_matrix 或 scipy.sparse.csc_matrix)转换为密集数组(即 NumPy 数组)。稀疏矩阵是一种特殊的矩阵表示形式,它只存储非零元素的位置和值,而不是存储整个矩阵的所有元素,这样可以节省内存和计算资源,特别是当矩阵非常稀疏时。toarray() 方法将稀疏矩阵转换为常规的二维数组,其中包含了所有元素,包括零元素。

  • to_sparse() :这个方法用于将密集张量(在 PyTorch 中是 torch.Tensor)转换为稀疏张量。在 PyTorch 中,稀疏张量是一种特殊的数据结构,它只存储非零元素的位置和值。这种表示形式对于处理大规模稀疏数据非常有用,因为它可以减少内存使用并提高计算效率。to_sparse() 方法创建一个稀疏张量,其中包含了密集张量中的非零元素。

  • 这行代码的意义在于:首先,它将原始的稀疏矩阵转换为密集数组,这可能是因为某些操作(如矩阵乘法)在密集数组上更容易执行,或者是因为需要将数据转换为 PyTorch 可以处理的格式。然后,它将密集数组转换回稀疏张量。这可能是因为在 PyTorch 中进行后续的稀疏矩阵操作,或者是因为稀疏张量在内存使用和计算效率方面有优势。

这篇关于【Python-图结构准备】“pickled object“、 调整邻接矩阵使其对称、图加自环 图邻接矩阵归一化、稀疏邻接矩阵格式转换的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Python FastAPI+Celery+RabbitMQ实现分布式图片水印处理系统

《PythonFastAPI+Celery+RabbitMQ实现分布式图片水印处理系统》这篇文章主要为大家详细介绍了PythonFastAPI如何结合Celery以及RabbitMQ实现简单的分布式... 实现思路FastAPI 服务器Celery 任务队列RabbitMQ 作为消息代理定时任务处理完整

Python Websockets库的使用指南

《PythonWebsockets库的使用指南》pythonwebsockets库是一个用于创建WebSocket服务器和客户端的Python库,它提供了一种简单的方式来实现实时通信,支持异步和同步... 目录一、WebSocket 简介二、python 的 websockets 库安装三、完整代码示例1.

揭秘Python Socket网络编程的7种硬核用法

《揭秘PythonSocket网络编程的7种硬核用法》Socket不仅能做聊天室,还能干一大堆硬核操作,这篇文章就带大家看看Python网络编程的7种超实用玩法,感兴趣的小伙伴可以跟随小编一起... 目录1.端口扫描器:探测开放端口2.简易 HTTP 服务器:10 秒搭个网页3.局域网游戏:多人联机对战4.

使用Python实现快速搭建本地HTTP服务器

《使用Python实现快速搭建本地HTTP服务器》:本文主要介绍如何使用Python快速搭建本地HTTP服务器,轻松实现一键HTTP文件共享,同时结合二维码技术,让访问更简单,感兴趣的小伙伴可以了... 目录1. 概述2. 快速搭建 HTTP 文件共享服务2.1 核心思路2.2 代码实现2.3 代码解读3.

Python使用自带的base64库进行base64编码和解码

《Python使用自带的base64库进行base64编码和解码》在Python中,处理数据的编码和解码是数据传输和存储中非常普遍的需求,其中,Base64是一种常用的编码方案,本文我将详细介绍如何使... 目录引言使用python的base64库进行编码和解码编码函数解码函数Base64编码的应用场景注意

Python基于wxPython和FFmpeg开发一个视频标签工具

《Python基于wxPython和FFmpeg开发一个视频标签工具》在当今数字媒体时代,视频内容的管理和标记变得越来越重要,无论是研究人员需要对实验视频进行时间点标记,还是个人用户希望对家庭视频进行... 目录引言1. 应用概述2. 技术栈分析2.1 核心库和模块2.2 wxpython作为GUI选择的优

Java实现时间与字符串互相转换详解

《Java实现时间与字符串互相转换详解》这篇文章主要为大家详细介绍了Java中实现时间与字符串互相转换的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、日期格式化为字符串(一)使用预定义格式(二)自定义格式二、字符串解析为日期(一)解析ISO格式字符串(二)解析自定义

Python如何使用__slots__实现节省内存和性能优化

《Python如何使用__slots__实现节省内存和性能优化》你有想过,一个小小的__slots__能让你的Python类内存消耗直接减半吗,没错,今天咱们要聊的就是这个让人眼前一亮的技巧,感兴趣的... 目录背景:内存吃得满满的类__slots__:你的内存管理小助手举个大概的例子:看看效果如何?1.

Python+PyQt5实现多屏幕协同播放功能

《Python+PyQt5实现多屏幕协同播放功能》在现代会议展示、数字广告、展览展示等场景中,多屏幕协同播放已成为刚需,下面我们就来看看如何利用Python和PyQt5开发一套功能强大的跨屏播控系统吧... 目录一、项目概述:突破传统播放限制二、核心技术解析2.1 多屏管理机制2.2 播放引擎设计2.3 专

Python中随机休眠技术原理与应用详解

《Python中随机休眠技术原理与应用详解》在编程中,让程序暂停执行特定时间是常见需求,当需要引入不确定性时,随机休眠就成为关键技巧,下面我们就来看看Python中随机休眠技术的具体实现与应用吧... 目录引言一、实现原理与基础方法1.1 核心函数解析1.2 基础实现模板1.3 整数版实现二、典型应用场景2