【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函数作用域示例详解

《Python函数作用域示例详解》本文介绍了Python中的LEGB作用域规则,详细解析了变量查找的四个层级,通过具体代码示例,展示了各层级的变量访问规则和特性,对python函数作用域相关知识感兴趣... 目录一、LEGB 规则二、作用域实例2.1 局部作用域(Local)2.2 闭包作用域(Enclos

Python实现对阿里云OSS对象存储的操作详解

《Python实现对阿里云OSS对象存储的操作详解》这篇文章主要为大家详细介绍了Python实现对阿里云OSS对象存储的操作相关知识,包括连接,上传,下载,列举等功能,感兴趣的小伙伴可以了解下... 目录一、直接使用代码二、详细使用1. 环境准备2. 初始化配置3. bucket配置创建4. 文件上传到os

关于集合与数组转换实现方法

《关于集合与数组转换实现方法》:本文主要介绍关于集合与数组转换实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、Arrays.asList()1.1、方法作用1.2、内部实现1.3、修改元素的影响1.4、注意事项2、list.toArray()2.1、方

使用Python实现可恢复式多线程下载器

《使用Python实现可恢复式多线程下载器》在数字时代,大文件下载已成为日常操作,本文将手把手教你用Python打造专业级下载器,实现断点续传,多线程加速,速度限制等功能,感兴趣的小伙伴可以了解下... 目录一、智能续传:从崩溃边缘抢救进度二、多线程加速:榨干网络带宽三、速度控制:做网络的好邻居四、终端交互

Python中注释使用方法举例详解

《Python中注释使用方法举例详解》在Python编程语言中注释是必不可少的一部分,它有助于提高代码的可读性和维护性,:本文主要介绍Python中注释使用方法的相关资料,需要的朋友可以参考下... 目录一、前言二、什么是注释?示例:三、单行注释语法:以 China编程# 开头,后面的内容为注释内容示例:示例:四

Python中win32包的安装及常见用途介绍

《Python中win32包的安装及常见用途介绍》在Windows环境下,PythonWin32模块通常随Python安装包一起安装,:本文主要介绍Python中win32包的安装及常见用途的相关... 目录前言主要组件安装方法常见用途1. 操作Windows注册表2. 操作Windows服务3. 窗口操作

Python中re模块结合正则表达式的实际应用案例

《Python中re模块结合正则表达式的实际应用案例》Python中的re模块是用于处理正则表达式的强大工具,正则表达式是一种用来匹配字符串的模式,它可以在文本中搜索和匹配特定的字符串模式,这篇文章主... 目录前言re模块常用函数一、查看文本中是否包含 A 或 B 字符串二、替换多个关键词为统一格式三、提

python常用的正则表达式及作用

《python常用的正则表达式及作用》正则表达式是处理字符串的强大工具,Python通过re模块提供正则表达式支持,本文给大家介绍python常用的正则表达式及作用详解,感兴趣的朋友跟随小编一起看看吧... 目录python常用正则表达式及作用基本匹配模式常用正则表达式示例常用量词边界匹配分组和捕获常用re

python实现对数据公钥加密与私钥解密

《python实现对数据公钥加密与私钥解密》这篇文章主要为大家详细介绍了如何使用python实现对数据公钥加密与私钥解密,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录公钥私钥的生成使用公钥加密使用私钥解密公钥私钥的生成这一部分,使用python生成公钥与私钥,然后保存在两个文

python删除xml中的w:ascii属性的步骤

《python删除xml中的w:ascii属性的步骤》使用xml.etree.ElementTree删除WordXML中w:ascii属性,需注册命名空间并定位rFonts元素,通过del操作删除属... 可以使用python的XML.etree.ElementTree模块通过以下步骤删除XML中的w:as