稀疏矩阵是一种特殊的矩阵,其非零元素数目远远少于零元素数目,并且非零元素分布没有规律。
这种矩阵在实际应用中经常出现,例如在物理学、图形学和网络通信等领域。
稀疏矩阵其实也可以和一般的矩阵一样处理,之所以要把它区分开来进行特殊处理,是因为:
一方面稀疏矩阵的存储空间开销通常比稠密矩阵要小得多,可以节省存储空间;
另一方面,在计算稀疏矩阵时,可以利用其特殊的结构,采用专门的算法,提高计算效率和准确性。
因此,稀疏矩阵在Scipy
库中被单独作为一个模块,以便被更好地处理和应用。
1. 主要功能
稀疏矩阵子模块(scipy.sparse
)的主要功能包括:
类别 | 说明 |
---|---|
稀疏数组类 | 支持各种格式的稀疏数组 |
稀疏矩阵类 | 支持各种格式的稀疏矩阵 |
稀疏矩阵工具 | 构建,保存,加载以及识别稀疏矩阵的各种函数 |
其他 | 包含压缩稀疏图例程,稀疏线性代数等子模块,以及一些异常处理方法 |
这里有个需要注意的地方是稀疏数组和稀疏矩阵的区别。
这两个类别中的很多函数名称也类似,比如:bsr服务器托管网_array
和bsr_matrix
,coo_array
和coo_matrix
等等。
只要区别在于:***_matrix
类的函数是一种基于Compressed Sparse Row(CSR)和Compressed Sparse Column(CSC)格式的块稀疏矩阵表示方法。
它使用一个字典来存储非零元素,其中每个元素对应于一个包含三个值的元组,分别表示该元素的行索引、列索引和非零元素的值。
这种数据结构可以提供更好的计算性能和内存使用效率,特别适合于大规模的块稀疏矩阵计算。
而***_array
类的函数虽然类似于***_matrix
的数据结构,但它允许更大的灵活性。***_array
可以表示任意的稀疏数组,而不仅仅是块稀疏矩阵。
它使用一个具有三个数组的元组来表示稀疏数组,其中第一个数组存储行索引,第二个数组存储列索引,第三个数组存储非零元素的值。
这种数据结构适用于更通用的稀疏数组计算,但可能不如***_matrix
高效。
总之,***_matrix
和***_array
都是用于表示块稀疏矩阵或稀疏数组的数据结构。***_matrix
更适合于大规模的块稀疏矩阵计算,而***_array
适用于更通用的稀疏数组计算。
2. 使用示例服务器托管网
稀疏矩阵之所以成为单独的一个模块,是因为它的稀疏的特性在很多领域多有广泛的应用。scipy.sparse
子模块中提供了大概7种:
- csc_matrix: 压缩稀疏列格式(Compressed Sparse Column)
- csr_matrix: 压缩稀疏行格式(Compressed Sparse Row)
- bsr_matrix: 块稀疏行格式(Block Sparse Row)
- lil_matrix: 列表格式的列表(List of Lists format)
- dok_matrix: 键格式字典(Dictionary of Keys)
- coo_matrix: 坐标格式(又名 IJV,三元组格式)
- dia_matrix: 对角线格式(DIAgonal format)
2.1. 使用稀疏矩阵
稀疏矩阵其实在运算上和使用普通矩阵一样。
首先,构造一个创建矩阵的方法create_matrix
,这个方法会生成一个10x10
的矩阵,
方法的参数N
表示随机在矩阵的N个位置中生成值。
from scipy import sparse
import numpy as np
# 创建一个10x10矩阵,其中有值的元素不超过N个
def create_matrix(N):
data = np.zeros((10, 10))
for _ in range(N):
row = np.random.randint(0, 10, 1)
col = np.random.randint(0, 10, 1)
data[row, col] = np.random.randint(1, 100, 1)
return data
create_matrix
创建的是普通矩阵,我们将生成的矩阵转换为稀疏矩阵后,计算方式差不多。
# 创建两个普通矩阵
m1 = create_matrix(8)
m2 = create_matrix(6)
# 计算点积
m1.dot(m2) # 返回m1和m2的点积结果
# 将普通矩阵变为稀疏矩阵
#(这里的演示用了7种类型中的一种bsr)
d1 = sparse.bsr_matrix(m1)
d2 = sparse.bsr_matrix(m2)
# 计算点积后,用toarray方法转换为二维数组
d1.dot(d2).toarray()
从上面的代码可以看出,用scipy.sparse
中的稀疏矩阵和使用一般矩阵差不多。
2.2. 稀疏矩阵的性能
我们使用稀疏矩阵,就是因为其运算性能比使用一般矩阵强,否则还不如直接用一般矩阵。
下面,简单测试下scipy.sparse
模块下稀疏矩阵的性能。
先看其内存占用是否有减少,为了让性能差别能显著看出,
先扩大测试矩阵为 1000x1000
。
import sys
def create_matrix(N):
data = np.zeros((1000, 1000))
for _ in range(N):
row = np.random.randint(0, 1000, 1)
col = np.random.randint(0, 1000, 1)
data[row, col] = np.random.randint(1, 100, 1)
return data
m1 = create_matrix(8)
m2 = create_matrix(6)
d1 = sparse.csr_matrix(m1)
d2 = sparse.csr_matrix(m2)
print("一般矩阵 m1 占用的空间:{}".format(sys.getsizeof(m1)))
print("一般矩阵 m2 占用的空间:{}".format(sys.getsizeof(m2)))
print("一般矩阵 d1 占用的空间:{}".format(sys.getsizeof(d1)))
print("一般矩阵 d2 占用的空间:{}".format(sys.getsizeof(d2)))
# 运行结果:
一般矩阵 m1 占用的空间:8000128
一般矩阵 m2 占用的空间:8000128
一般矩阵 d1 占用的空间:56
一般矩阵 d2 占用的空间:56
可以看出占用的空间明显缩小了。
再看点积的运算性能:(运行10轮,每轮100次)
%%timeit -r 10 -n 100
m1.dot(m2)
# 运行结果:
10.6 ms 136 s per loop (mean std. dev. of 10 runs, 100 loops each)
稀疏矩阵的点积运算:
%%timeit -r 10 -n 100
d1.dot(d2)
# 运行结果:
137 s 14.3 s per loop (mean std. dev. of 10 runs, 100 loops each)
可以看出,运算性能差别非常大,一个是毫秒级别(10.6ms
)的,一个是微秒级别(137 s
)的。
3. 总结
稀疏矩阵在矩阵中只是一种特殊的矩阵,然而在实际应用领域中,却应用极广,比如:
在数值计算中,可以用于解决大规模线性代数方程组、大规模非线性方程组和非线性优化问题,以及求解大规模约束规划问题。
在模式识别中,如人脸识别、手写数字识别、文本分类等任务,可用于表示高维数据,提取特征并进行降维,提高识别准确率和计算效率。
在推荐系统中,处理大量用户和物品的数据时,稀疏矩阵可以有效地表示这些数据。
在社交网络中,因为一般社交关系都是稀疏的,所以可用于分析社交网络的结构和行为,例如社区检测、影响力传播。
此外,还可以用在计算机视觉,自然语言处理,生物信息学等等领域。
所以,研究稀疏矩阵有其重要的实际意义。
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.fwqtg.net
相关推荐: 从 5s 到 0.5s!CompletableFuture 异步任务优化技巧,确实优雅!
一个接口可能需要调用 N 个其他服务的接口,这在项目开发中还是挺常见的。举个例子:用户请求获取订单信息,可能需要调用用户信息、商品详情、物流信息、商品推荐等接口,最后再汇总数据统一返回。 如果是串行(按顺序依次执行每个任务)执行的话,接口的响应速度会非常慢。考…