首页 文章

从python中给定大型稀疏矩阵的不同行的操作创建一个新的稀疏矩阵

提问于
浏览
1

比方说,S是大SciPy的-CSR矩阵(稀疏),并用键的字典d - 在S&值的行矢量A>指数(位置) - >其他行向量的所有索引(位置)的列表在S中,对于l中的每个行向量,您减去A并获得新的向量,该向量将只是要在新的稀疏矩阵中更新的新行向量 .

形式字典 - > { 1 : [4 , 5 ,... ,63] }然后必须用....创建一个新的稀疏矩阵

new_row_vector_1 - > S_vec 1 - S_vec 4

new_row_vector_2 - > S_vec 1 - S_vec 5

.

new_row_vector_n - > S_vec 1 - S_vec 63

其中S_vecX是矩阵S的第X行向量

Check out the pictorial explanation of the above statements

Numpy示例:

>>> import numpy as np
>>> s = np.array([[1,5,3,4],[3,0,12,7],[5,6,2,4],[4,6,6,4],[7,12,5,67]])
>>> s
array([[ 1,  5,  3,  4],
       [ 3,  0, 12,  7],
       [ 5,  6,  2,  4],
       [ 4,  6,  6,  4],
       [ 7, 12,  5, 67]])
>>> index_dictionary = {0: [2, 4], 1: [3, 4], 2: [1], 3: [1, 2], 4: [1, 3, 2]} 
>>> n = np.zeros((10,4)) #sum of all lengths of values in index_dictionary would be the number of rows for the new array(n) and columns remain the same as s.
>>> n
array([[ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.]])
>>> idx = 0
>>> for index in index_dictionary:
...     for k in index_dictionary[index]:
...             n[idx] = s[index]-s[k]
...             idx += 1
... 
>>> n
array([[ -4.,  -1.,   1.,   0.],
       [ -6.,  -7.,  -2., -63.],
       [ -1.,  -6.,   6.,   3.],
       [ -4., -12.,   7., -60.],
       [  2.,   6., -10.,  -3.],
       [  1.,   6.,  -6.,  -3.],
       [ -1.,   0.,   4.,   0.],
       [  4.,  12.,  -7.,  60.],
       [  3.,   6.,  -1.,  63.],
       [  2.,   6.,   3.,  63.]])

我是我想要的 .

1 回答

  • 0

    这是我认为你想要做的简单演示:

    首先是numpy数组版本:

    In [619]: arr=np.arange(12).reshape(4,3)
    In [620]: arr[[1,0,2,3]]-arr[0] 
    Out[620]: 
    array([[3, 3, 3],
           [0, 0, 0],
           [6, 6, 6],
           [9, 9, 9]])
    

    现在稀疏的等价物:

    In [622]: M=sparse.csr_matrix(arr)
    

    csr 实现行索引:

    In [624]: M[[1,0,2,3]]
    Out[624]: 
    <4x3 sparse matrix of type '<class 'numpy.int32'>'
        with 11 stored elements in Compressed Sparse Row format>
    In [625]: M[[1,0,2,3]].A
    Out[625]: 
    array([[ 3,  4,  5],
           [ 0,  1,  2],
           [ 6,  7,  8],
           [ 9, 10, 11]], dtype=int32)
    

    但不是广播:

    In [626]: M[[1,0,2,3]]-M[0]
     ....
    ValueError: inconsistent shapes
    

    所以我们可以使用一种明确的广播形式

    In [627]: M[[1,0,2,3]]-M[[0,0,0,0]]  # or M[[0]*4]
    Out[627]: 
    <4x3 sparse matrix of type '<class 'numpy.int32'>'
        with 9 stored elements in Compressed Sparse Row format>
    In [628]: _.A
    Out[628]: 
    array([[3, 3, 3],
           [0, 0, 0],
           [6, 6, 6],
           [9, 9, 9]], dtype=int32)
    

    这可能不是最快或最有效的,但它是一个开始 .

    我在之前的SO问题中发现 M[[1,0,2,3]] 索引是使用矩阵乘法执行的,在这种情况下相当于:

    idxM = sparse.csr_matrix(([1,1,1,1],([0,1,2,3],[1,0,2,3])),(4,4))
    M1 = idxM * M
    

    Sparse matrix slicing using list of int

    所以我的差异表达式需要2次这样的乘法以及减法 .

    我们可以尝试逐行迭代,并从结果中构建一个新矩阵,但不能保证它会更快 . 根据阵列的不同,转换为密集和后退可能会更快 .

    =================

    我可以想象两种方法将其应用到字典中 .

    一种是迭代字典(什么顺序?),为每个键执行这种差异,在列表中收集结果(稀疏矩阵列表),并使用 sparse.bmat 将它们连接成一个矩阵 .

    另一种方法是收集两个索引列表,并仅应用上面的索引差异一次 .

    In [8]: index_dictionary = {0: [2, 4], 1: [3, 4], 2: [1], 3: [1, 2], 4: [1, 3, 2]} 
    In [10]: alist=[]
        ...: for index in index_dictionary:
        ...:     for k in index_dictionary[index]:
        ...:         alist.append((index, k))       
    In [11]: idx = np.array(alist)
    In [12]: idx
    Out[12]: 
    array([[0, 2],
           [0, 4],
           [1, 3],
           [1, 4],
           [2, 1],
           [3, 1],
           [3, 2],
           [4, 1],
           [4, 3],
           [4, 2]])
    

    适用于你的密集 s

    In [15]: s = np.array([[1,5,3,4],[3,0,12,7],[5,6,2,4],[4,6,6,4],[7,12,5,67]])
    In [16]: s[idx[:,0]]-s[idx[:,1]]
    Out[16]: 
    array([[ -4,  -1,   1,   0],
           [ -6,  -7,  -2, -63],
           [ -1,  -6,   6,   3],
           [ -4, -12,   7, -60],
           [  2,   6, -10,  -3],
           [  1,   6,  -6,  -3],
           [ -1,   0,   4,   0],
           [  4,  12,  -7,  60],
           [  3,   6,  -1,  63],
           [  2,   6,   3,  63]])
    

    和稀疏的等价物

    In [19]: arr= sparse.csr_matrix(s)
    In [20]: arr
    Out[20]: 
    <5x4 sparse matrix of type '<class 'numpy.int32'>'
        with 19 stored elements in Compressed Sparse Row format>
    In [21]: res=arr[idx[:,0]]-arr[idx[:,1]]
    In [22]: res
    Out[22]: 
    <10x4 sparse matrix of type '<class 'numpy.int32'>'
        with 37 stored elements in Compressed Sparse Row format>
    

相关问题