【问题标题】:Consecutive elements in a Sparse matrix row稀疏矩阵行中的连续元素
【发布时间】:2017-02-26 05:51:50
【问题描述】:

我正在研究以 COO 格式存储的稀疏矩阵。获取每行连续元素数的最快方法是什么。

例如考虑以下矩阵:

a = [[0,1,2,0],[1,0,0,2],[0,0,0,0],[1,0,1,0]]

它的首席运营官代表是

  (0, 1)    1
  (0, 2)    2
  (1, 0)    1
  (1, 3)    2
  (3, 0)    1
  (3, 2)    1

我需要结果为[1,2,0,2]。第一行包含两个位于附近的非零元素。因此它是一个组或集合。在第二行中,我们有两个非零元素,但它们不在附近,因此我们可以说它形成了两个组。第三行没有非零,因此没有组。第四行再次有两个非零,但由零隔开,因此我们将其视为两组。这就像每行的集群数。遍历行是一种选择,但前提是没有更快的解决方案。感谢您在这方面的任何帮助。

另一个简单的例子:考虑下面一行:

[1,2,3,0,0,0,2,0,0,8,7,6,0,0]

上面的行应该返回[3] sine,三组非零被零隔开。

【问题讨论】:

  • (1) 我看不懂这个例子。 (2) 如果您的稀疏矩阵是为它设计的,那么迭代行方法是完美的。所以先转换成csr_matrix(从coo转换效​​率很高!)
  • @sascha 它只是查找行中的组数。一组由连续的元素组成。我将更新问题以使其更清楚

标签: python python-2.7 matrix scipy sparse-matrix


【解决方案1】:

将其转换为密集数组,并逐行应用您的逻辑。

  • 您想要每行的组数
  • 定义组时的零计数
  • 数组的行迭代速度更快

coo 格式中,您的矩阵如下所示:

In [623]: M=sparse.coo_matrix(a)
In [624]: M.data
Out[624]: array([1, 2, 1, 2, 1, 1])
In [625]: M.row
Out[625]: array([0, 0, 1, 1, 3, 3], dtype=int32)
In [626]: M.col
Out[626]: array([1, 2, 0, 3, 0, 2], dtype=int32)

这种格式不实现行索引; csrlil

In [627]: M.tolil().data
Out[627]: array([[1, 2], [1, 2], [], [1, 1]], dtype=object)
In [628]: M.tolil().rows
Out[628]: array([[1, 2], [0, 3], [], [0, 2]], dtype=object)

所以第一行的稀疏信息是一个非零数据值列表[1,2],以及它们的列号列表[1,2]。将其与密集数组的行进行比较,[0, 1, 2, 0]。哪个更容易分析?

您的第一个任务是编写一个分析一行的函数。我还没有充分研究你的逻辑来说明密集形式是否比稀疏形式更好。使用M.A[0,:].nonzero(),很容易从密集形式中获取列信息。

在你的最后一个例子中,我可以得到非零索引:

In [631]: np.nonzero([1,2,3,0,0,0,2,0,0,8,7,6,0,0])
Out[631]: (array([ 0,  1,  2,  6,  9, 10, 11], dtype=int32),)
In [632]: idx=np.nonzero([1,2,3,0,0,0,2,0,0,8,7,6,0,0])[0]
In [633]: idx
Out[633]: array([ 0,  1,  2,  6,  9, 10, 11], dtype=int32)
In [634]: np.diff(idx)
Out[634]: array([1, 1, 4, 3, 1, 1], dtype=int32)

我们可以从diff>1 的数量中获得所需的计数,但我必须查看更多示例来定义细节。

将分析扩展到多行取决于首先彻底了解单行情况。

【讨论】:

    【解决方案2】:

    @hpaulj 的评论的帮助下,我想出了以下 sn-p 来做到这一点:

        M = m.tolil()
    r = []  
    for i in range(M.shape[0]):
       sumx=0
       idx= M.rows[i]
       if (len(idx) > 2):
           tempidx = np.diff(idx)
           if (1 in tempidx):
               temp = filter(lambda a: a != 1, tempidx)
               sumx=1
           counts = len(temp)
           r.append(counts+sumx)
       elif (len(idx) == 2):
           tempidx = np.diff(idx)
           if(tempidx[0]==1):
               counts = 1
               r.append(counts)
           else:
               counts = 2
               r.append(counts)
       elif (len(idx) == 1):
           counts = 1
           r.append(counts) 
       else:
           counts = 0
           r.append(counts)
    tempcluster = np.sum(r)/float(M.shape[0])
    cluster.append(tempcluster)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-25
      • 2021-12-30
      • 2017-04-16
      • 2012-01-10
      • 2012-06-20
      • 2013-02-13
      相关资源
      最近更新 更多