稀疏矩阵详解:csr_matrix和csc_matrix

在运算时,会存在大量的稀疏矩阵,比如单位阵,会造成空间浪费。

这时就采用矩阵压缩的方式来表述,数据不变,存储形式发生改变,省很多空间。

即,scipy库中的sparse.csr_matrix(csr:Compressed Sparse Row marix)
sparse.csc_matric(csc:Compressed Sparse Column marix)

刚开始看官方文档有点儿拗,自己用官方样例详细解释了一遍,感觉理解容易多了

csr_matrix()

def test_csr():
    '''
    # 原始矩阵orig样例:
    orig = array([[1, 0, 2],
                [0, 0, 3],
                [4, 5, 6]])

    CSR: 按【行row】来压缩,便于理解,进行重命名
    
        count,就是官方的indptr,是一个递增数组
            含义:【差值】是统计原始矩阵每【行】【非0数据】的【个数】,
                反向理解,就是【累加】原始矩阵每行的【非0数据】的【个数】
                对于count数组,假设索引为i,
                count[i+1] - count[i]就是原始矩阵【第i行】的【非0数据】的【个数】
            样例:
                当i=0时,count[1] - count[0] = 2-0 = 2, 表示原始矩阵【第0行】的【非0数据】有【2个】
                当i=1时,count[2] - count[1] = 3-2 = 1, 表示原始矩阵【第1行】的【非0数据】有【1个】
                当i=2时,count[3] - count[2] = 6-3 = 3, 表示原始矩阵【第2行】的【非0数据】有【3个】
                
        index, 就是官方的indices,是一个【列索引】数组
            含义:对于CSR,这里就是【列】的索引,即表示原始矩阵当前行中的【非0数据】所在的【列索引值】
                对于index和count数组,假设索引为i,
                index[count[i]: count[i+1]]表示原始矩阵中【第i行】的【非0数据】所在的【列索引值】
                ps:注意中间是【冒号】
                
            样例:
                当i=0时,index[count[0]:count[1]] = index[0:2]= [0,2], 
            表示原始矩阵【第0行】的【2个】【非0数据】所在的【列索引值】为0和2,即定位为orig[0,0]和orig[0,2]
                当i=1时,index[count[1]:count[2]] = index[2:3]= [2], 
            表示原始矩阵【第0行】的【1个】【非0数据】所在的【列索引值】为2,即定位为orig[1,2]
                当i=2时,index[count[2]:count[3]] = index[3:6]= [0,1,2], 
            表示原始矩阵【第0行】的【3个】【非0数据】所在的【列索引值】为0,1,2,即定位为orig[2,0], orig[2,1]和orig[2,2]
            
        data,保持不变, 按行顺序,存储【非0数据】的数组
            含义:根据index数组找到每行中【非0数据】的【列索引值】,依次存取数据即可
                对于data和count数组,假设索引为i,
                data[count[i]: count[i+1]]表示原始矩阵中【第i行】的【非0数据】的【值】
            样例:
                当i=0时,data[count[0]:count[1]] = data[0:2]= [1,2], 
            表示原始矩阵【第0行】的【2个】【非0数据】,即定位为orig[0,0] =1 和orig[0,2]=2
                当i=1时,index[count[1]:count[2]] = index[2:3]= [2], 
            表示原始矩阵【第0行】的【1个】【非0数据】,即定位为orig[1,2]=3
                当i=2时,index[count[2]:count[3]] = index[3:6]= [0,1,2], 
            表示原始矩阵【第0行】的【3个】【非0数据】,即定位为orig[2,0]=4, orig[2,1]=5 和orig[2,2]=6
    '''
    
    count = np.array([0, 2, 3, 6])
    index = np.array([0, 2, 2, 0, 1, 2])
    data = np.array([1, 2, 3, 4, 5, 6])

    # 将稀疏矩阵转为原始矩阵
    orig = csr_matrix((data, index, count), shape=(3, 3)).toarray()
    # 将原始矩阵转为稀疏矩阵
    res = csr_matrix(orig)
    
    print(res.indptr) 
    # [0 2 3 6] 
    print(res.indices)
    # [0 2 2 0 1 2]
    print(res.data)
    # [1 4 5 2 3 6]
    print(orig)
    # [[1 0 2]
    #  [0 0 3]    
    # [4 5 6]]
    print(res)
    # (0, 0)        1
    # (0, 2)        2
    # (1, 2)        3
    # (2, 0)        4
    # (2, 1)        5
    # (2, 2)        6

csc_matrix()

def test_csc():
    '''
    
    # 原始矩阵orig样例:
    orig = array([[1, 0, 4],
                [0, 0, 5],
                [2, 3, 6]])

    CSC: 按【列col】来压缩,便于理解,进行重命名
    
        count,就是官方的indptr,是一个递增数组
            含义:【差值】是统计原始矩阵每【列】【非0数据】的【个数】,
                反向理解,就是【累加】原始矩阵每列的【非0数据】的【个数】
                对于count数组,假设索引为i,
                count[i+1] - count[i]就是原始矩阵【第i列】的【非0数据】的【个数】
            样例:
                当i=0时,count[1] - count[0] = 2-0 = 2, 表示原始矩阵【第0列】的【非0数据】有【2个】
                当i=1时,count[2] - count[1] = 3-2 = 1, 表示原始矩阵【第1列】的【非0数据】有【1个】
                当i=2时,count[3] - count[2] = 6-3 = 3, 表示原始矩阵【第2列】的【非0数据】有【3个】
                
        index, 就是官方的indices,是一个【行索引】数组
            含义:对于CSC,这里就是【行】的索引,即表示原始矩阵当前列中的【非0数据】所在的【行索引值】
                对于index和count数组,假设索引为i,
                index[count[i]: count[i+1]]表示原始矩阵中【第i列】的【非0数据】所在的【行索引值】
                ps:注意中间是【冒号】
                
            样例:
                当i=0时,index[count[0]:count[1]] = index[0:2]= [0,2], 
            表示原始矩阵【第0列】的【2个】【非0数据】所在的【行索引值】为0和2,即定位为orig[0,0]和orig[2,0]
                当i=1时,index[count[1]:count[2]] = index[2:3]= [2], 
            表示原始矩阵【第0列】的【1个】【非0数据】所在的【行索引值】为2,即定位为orig[2,1]
                当i=2时,index[count[2]:count[3]] = index[3:6]= [0,1,2], 
            表示原始矩阵【第0列】的【3个】【非0数据】所在的【行索引值】为0,1,2,即定位为orig[0,2], orig[1,2]和orig[2,2]
            
        data,保持不变, 按列顺序,存储【非0数据】的数组
            含义:根据index数组找到每列中【非0数据】的【行索引值】,依次存取数据即可
                对于data和count数组,假设索引为i,
                data[count[i]: count[i+1]]表示原始矩阵中【第i列】的【非0数据】的【值】
            样例:
                当i=0时,data[count[0]:count[1]] = data[0:2]= [1,2], 
            表示原始矩阵【第0列】的【2个】【非0数据】,即定位为orig[0,0] =1 和orig[2,0]=2
                当i=1时,index[count[1]:count[2]] = index[2:3]= [2], 
            表示原始矩阵【第0列】的【1个】【非0数据】,即定位为orig[2,1]=3
                当i=2时,index[count[2]:count[3]] = index[3:6]= [0,1,2], 
            表示原始矩阵【第0列】的【3个】【非0数据】,即定位为orig[0,2]=4, orig[1,2]=5 和orig[2,2]=6
    '''
    
    count = np.array([0, 2, 3, 6])
    index = np.array([0, 2, 2, 0, 1, 2])
    data = np.array([1, 2, 3, 4, 5, 6])

    # 将稀疏矩阵转为原始矩阵
    orig = csc_matrix((data, index, count), shape=(3, 3)).toarray()
    # 将原始矩阵转为稀疏矩阵
    res = csc_matrix(orig)
    
    print(res.indptr) 
    # [0 2 3 6]
    print(res.indices)
    # [0 2 2 0 1 2]
    print(res.data)
    # [1 4 5 2 3 6]
    print(orig)
    # [[1 0 4]
    # [0 0 5]
    # [2 3 6]]
    print(res)
    # (0, 0)        1
    # (2, 0)        2
    # (2, 1)        3
    # (0, 2)        4
    # (1, 2)        5
    # (2, 2)        6
  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值