稀疏矩阵(Sparse Matirx):一个矩阵的大部分元素为零
对于稀疏矩阵而言,实际存储的数据项很少,如果用传统的二维数组的方式来存储稀疏矩阵,会十分浪费计算机的内存空间。

C=[[None]*N for row in range(N)]

提高内存空间利用率的方法就是利用三项式(3-tuple)的数据结构,把每一个非零项以(i,j,item-value)来表示。
就是假如一个稀疏矩阵有n个非零项,那么可以利用一个A(0:n,1:3)的二维数组来存储这些非零项,这样存储的矩阵叫压缩矩阵。其中,A(0,1)存储这个稀疏矩阵的行数,A(0,2)存储这个稀疏矩阵的列数,而A(0,3)则是此稀疏矩阵非零项的总数。另外,每一个非零项以(i,j,item-value)来表示:
i为此矩阵非零项所在的行数
j为此矩阵非零项所在的列数
item-value则为此矩阵非零的值

一、压缩稀疏矩阵

设计一个Python程序来利用三项式(3-tuple)数据结构,并压缩 6 x 6稀疏矩阵,以减少内存不必要的浪费

NONZERO=0#记录非零项个数
temp=1
#声明稀疏矩阵
Sparse=[[15,0,0,22,0,-15],[0,11,3,0,0,0],[0,0,0,-6,0,0],

        [0,0,0,0,0,0],[91,0,0,0,0,0],[0,0,28,0,0,0]]
#声明压缩矩阵
Compress=[[None]*3 for row in range(9)]

print('稀疏矩阵的各个元素')
for i in range(6):
    for j in range(6):
        print('%d' %Sparse[i][j],end='\t')
        if Sparse[i][j]!=0:
            NONZERO=NONZERO+1
    print()

#开始压缩稀疏矩阵
Compress[0][0]=6        #矩阵的行数
Compress[0][1]=6        #矩阵的列数
Compress[0][2]=NONZERO  #矩阵非零项的总数
for i in range(6):
    for j in range(6):
        if Sparse[i][j]!=0:
                Compress[temp][0]=i
                Compress[temp][1]=j
                Compress[temp][2]=Sparse[i][j]
                temp=temp+1

print('稀疏矩阵压缩后的内容')
for i in range(NONZERO+1):
    for j in range(3):
        print('%d' %Compress[i][j],end='\t')
    print()

运行结果:

pytorch将稀疏矩阵coo转换为稠密矩阵 python稀疏矩阵计算_一维数组


二、稀疏矩阵的相关操作

例如:矩阵的转置

“转置矩阵”就是把原矩阵的行坐标元素与列坐标元素相互调换

A[i,j]转置=A[j,i]

如果直接将稀疏矩阵进行转置,只需要使用两个for循环,时间复杂度为O(columns x rows);

如果用三项式存储的压缩矩阵,它首先会确定在原稀疏矩阵中每一列的元素个数。

可以事先确定转置矩阵中每一行的起始位置,接着将原稀疏矩阵中的原素一个个的放到转置矩阵中的正确位置,这样做的时间复杂度O(columns+rows)三、上三角矩阵压缩为一维数组

上三角矩阵(Upper Triangle Matrix):就是一种对角线以下元素都为0的n x n矩阵;

又可分为右上三角矩阵(Right Upper Triangle Matr)与左上三角函数(Left Upper Triangle Matr);

右上三角矩阵:

pytorch将稀疏矩阵coo转换为稠密矩阵 python稀疏矩阵计算_稀疏矩阵_02


共有非零项:

pytorch将稀疏矩阵coo转换为稠密矩阵 python稀疏矩阵计算_一维数组_03


此二维矩阵的非零项可按序列映射到一维矩阵,且需要一个一维数组

pytorch将稀疏矩阵coo转换为稠密矩阵 python稀疏矩阵计算_一维数组_04


来存储,映射方式分为以行为组与以列为主两种数组内存分配的方式;

pytorch将稀疏矩阵coo转换为稠密矩阵 python稀疏矩阵计算_一维数组_05


以行为组:

pytorch将稀疏矩阵coo转换为稠密矩阵 python稀疏矩阵计算_Python 学习_06


假设有一个5X5的右上三角矩阵A,以行为主映射到一维数组B:

#上三角矩阵
global ARRAY_SIZE #矩阵的维数大小
ARRAY_SIZE=5

#一维数组的声明
num=int(ARRAY_SIZE*(ARRAY_SIZE+1)/2)
B=[None]*(num+1)

def getValue(i,j):
    index=int(ARRAY_SIZE*i-i*(i+1)/2+j)
    return B[index]

#上三角矩阵的内容
A=[[7,8,9,10,12],
   [0,5,4,3,2],
   [0,0,5,6,45],
   [0,0,0,3,2],
   [0,0,0,0,100]]
print(' -----------上三角矩阵----------------')

for i in range(ARRAY_SIZE):
    for j in range(ARRAY_SIZE):
        print('%d' %A[i][j],end='\t')
    print()

#将右上三角矩阵压缩为一维数组
index=0
for i in range(ARRAY_SIZE):
    for j in range(ARRAY_SIZE):
        if(A[i][j]!=0):
            index=index+1
            B[index]=A[i][j]
            1

print('---------以一维数组的方式表示-------------')
print('[',end=' ')
for i in range(ARRAY_SIZE):
    for j in range(i+1,ARRAY_SIZE+1):
        print('%d' %getValue(i,j),end=' ')
print(']')

pytorch将稀疏矩阵coo转换为稠密矩阵 python稀疏矩阵计算_稀疏矩阵_07