• 稀疏矩阵在Python中的表示方法


    对于一个矩阵而言,若数值为零的元素远远多于非零元素的个数,且非零元素分布没有规律时,这样的矩阵被称作稀疏矩阵;与之相反,若非零元素数目占据绝大多数时,这样的矩阵被称作稠密矩阵。

    稀疏矩阵在工程应用中经常被使用,尤其是在通信编码和机器学习中。若编码矩阵或特征表达矩阵是稀疏矩阵时,其计算速度会大大提升。对于机器学习而言,稀疏矩阵应用非常广,比如在数据特征表示、自然语言处理等领域。用稀疏表示和工作在计算上代价很高,需要专门处理稀疏矩阵的表示和操作等,但是这些操作可以大幅提升性能。

    Python中的稀疏矩阵

    SciPy使用多个数据结构为创建稀疏矩阵提供了工具,以及将稠密矩阵转化为稀疏矩阵的工具。许多在Numpy数组上运行的线性代数Numpy和SciPy函数可以在SciPy稀疏数组上操作。此外,使用Numpy数据结构的机器学习库也可以在Scipy稀疏数组上操作,例如,用于机器学习的scikit-learning和用于深度学习的Keras。

    Scipy中有可以表示的7种稀疏矩阵类型:

    1. csc_matrix: Compressed Sparse Column format
    2. csr_matrix: Compressed Sparse Row format
    3. bsr_matrix: Block Sparse Row format
    4. lil_matrix: List of Lists format
    5. dok_matrix: Dictionary of Keys format
    6. coo_matrix: COOrdinate format (aka IJV, triplet format)
    7. dia_matrix: DIAgonal format

    下面介绍常用的几种稀疏矩阵类型:

    coo_matrix

    coo_matrix是最简单的存储方式。采用三个数组row、col和data保存非零元素的行下标,列下标与值。这三个数组的长度相同。一般来说,coo_matrix主要用来创建矩阵,因为coo_matrix无法对矩阵的元素进行增删改等操作,一旦创建之后,除了将之转换成其它格式的矩阵,几乎无法对其做任何操作和矩阵运算

    >>> row = [0, 1, 2, 2]
    >>> col = [0, 1, 2, 3]
    >>> data = [1, 2, 3, 4]
    # 生成coo格式的矩阵
    >>> coo_mat = sparse.coo_matrix((data, (row, col)), shape=(4, 4))
    >>> coo_mat
    <4x4 sparse matrix of type '<class 'numpy.int32'>'
        with 4 stored elements in COOrdinate format>
    >>> coo_mat.toarray()
    array([[1, 0, 0, 0],
           [0, 2, 0, 0],
           [0, 0, 3, 4],
           [0, 0, 0, 0]])
    

    优点:

    • 转换成其它存储格式很快捷简便,转换成csr/csc很快
    • 允许重复的索引(例如在1行1列处存了值2.0,又在1行1列处存了值3.0,则转换成其它矩阵时就是2.0+3.0=5.0)

    缺点:

    • 不支持切片和算术运算操作

    dok_matrix与lil_matrix

    dok_matrix和lil_matrix适用的场景是逐渐添加矩阵的元素。dok_matrix的策略是采用字典来记录矩阵中不为0的元素。所以字典的key存的是记录元素的位置信息的元祖,value是记录元素的具体值。

    >>> S = sparse.dok_matrix((5, 5), dtype=np.float32)
    >>> for i in range(5):
          for j in range(5):
            S[i,j] = i+j    # 更新元素
    
    >>> S.toarray()
    [[0. 1. 2. 3. 4.]
     [1. 2. 3. 4. 5.]
     [2. 3. 4. 5. 6.]
     [3. 4. 5. 6. 7.]
     [4. 5. 6. 7. 8.]]
    

    优点:

    • 对于递增的构建稀疏矩阵很高效,比如定义该矩阵后,想进行每行每列更新值,可用该矩阵。当访问某个单元,只需要O(1)

    缺点:

    • 不允许重复索引(coo中适用),但可以很高效的转换成coo后进行重复索引

    lil_matrix则是使用两个列表存储非0元素。data保存每行中的非零元素,rows保存非零元素所在的列。这种格式也很适合逐个添加元素,并且能快速获取行相关的数据。

    >>> l = sparse.lil_matrix((4, 4))
    >>> l[1, 1] = 1
    >>> l[1, 3] =2
    >>> l[2, 3] = 3
    >>> l.toarray()
    array([[0., 0., 0., 0.],
           [0., 1., 0., 2.],
           [0., 0., 0., 3.],
           [0., 0., 0., 0.]])
    

    优点:

    • 适合递增的构建成矩阵
    • 转换成其它存储方式很高效
    • 支持灵活的切片

    缺点:

    • 当矩阵很大时,考虑用coo
    • 算术操作,列切片,矩阵向量内积操作慢

    csr_matrix与csc_matrix

    csr_matrix是按行对矩阵进行压缩的,csc_matrix是按列对矩阵进行压缩的。通过row_offsets,column_indices,data来确定矩阵。column_indices,data与coo格式的列索引与数值的含义完全相同,row_offsets表示元素的行偏移量。
    用如下例子说明:

    >>> indptr = np.array([0, 2, 3, 6]) # 元素的行偏移量
    >>> indices = np.array([0, 2, 2, 0, 1, 2])  # 列索引
    >>> data = np.array([1, 2, 3, 4, 5, 6])
    >>> csr_matrix((data, indices, indptr), shape=(3, 3)).toarray()
    array([[1, 0, 2],
           [0, 0, 3],
           [4, 5, 6]])
    

    以官方文档为例,此时data代表的是存储的值的数组,indices代表的是每一行中第几列有对应data中的元素,即从indices中可以推断出列的信息,indptr则用来推断出行的信息,默认元素开始为0,第一个元素为2,则证明第一行中有2-0=2个元素,所以将data数组中前另个元素写入第一行中,而indices前两个元素为0,2,则代表第0列和第2列。前两第二个元素为3,证明第二行中有3-2=1个元素,该元素为data[2]=3,且存储在indices[2] = 2列中。依次类推。

    CSR格式常用于读入数据后进行稀疏矩阵计算。

    CSR:
    优点:

    • 高效的稀疏矩阵算术操作
    • 高效的行切片
    • 快速地矩阵向量内积操作

    缺点:

    • 缓慢地列切片操作(可以考虑csc)
    • 转换到稀疏结构代价较高(可以考虑lil,dok)

    CSC:
    优点:

    • 高效的稀疏矩阵算术操作
    • 高效的列切片
    • 快速地矩阵向量内积操作(不如csr,bsr块)

    缺点:

    • 缓慢地行切片操作(可以考虑csr)
    • 转换到稀疏结构代价较高(可以考虑lil,dok)

    稀疏矩阵的存取

    用save_npz保存单个稀疏矩阵

    >>> scipy.sparse.save_npz('sparse_matrix.npz', sparse_matrix)
    >>> sparse_matrix = scipy.sparse.load_npz('sparse_matrix.npz')
    

    参考:
    python稀疏矩阵的存储与表示
    机器学习稀疏矩阵简介

  • 相关阅读:
    内网Windows Server时间自动同步
    处理sqlserver数据
    virtualenv使用
    vue过渡动画效果
    vue视图
    vue组件
    Vue实例
    vue介绍
    Bootstrap布局
    Bootstrap组件
  • 原文地址:https://www.cnblogs.com/hellojamest/p/11769467.html
Copyright © 2020-2023  润新知