在coo_matrix(scipy 稀疏矩阵)中,如何选择并返回每行中的"random column index",不包括该行中的非零索引?



我是Python的新手,这似乎很幼稚。我正在与COO_MATRIX(SCIPY稀疏矩阵) M 一起返回M:

row_index,column_index,random_index

有以下条件:

  1. row_index,column_index必须指向m
  2. 的非零条目
  3. row_index,column_index与所有非零条目相对应
  4. 对于每对ROW_INDEX,column_index,Random_index的
  5. Random_index应在m
  6. 的[0,total_num_columns]的范围内
  7. Random_Index不应在所有列索引的集合中,该列指向该row_index的某些非零值

我可以提出以下功能:

 def get_triplets(M):
return M.row, M.col, np.random.randint(M.shape[1], size=len(M.row))

除上述功能外,一切都很好,除了三重态的最后一个条目 - Random_Index 不是以期望的方式。不能保证随机索引不会在该行的一组非零索引中。换句话说,条件号(5)不满足

是否有一种有效的方式返回符合上述所有5条条件的三胞胎。希望我能使自己清晰明了,我感谢您在解决我的问题方面的任何帮助

谢谢

对于COO矩阵MM.rowM.colM.data是定义矩阵的3个数组,共同识别所有非零条目。它们可能是无序的,并且可能包含重复。

In [1]: from scipy import sparse
In [2]: row=[0,0,1,1,1,2,2]
In [3]: col=[0,2,0,1,0,1,2]
In [4]: data=[1,2,3,4,5,6,7]
In [5]: M=sparse.coo_matrix((data,(row,col)))
In [6]: M
Out[6]: 
<3x3 sparse matrix of type '<class 'numpy.int32'>'
    with 7 stored elements in COOrdinate format>
In [7]: print(M)
  (0, 0)    1
  (0, 2)    2
  (1, 0)    3
  (1, 1)    4
  (1, 0)    5
  (2, 1)    6
  (2, 2)    7
In [8]: M.A
Out[8]: 
array([[1, 0, 2],
       [8, 4, 0],
       [0, 6, 7]])

我们可以制作它的规范 - 对以下重复进行分类:

In [9]: M.sum_duplicates()
In [10]: print(M)
  (0, 0)    1
  (1, 0)    8
  (1, 1)    4
  (2, 1)    6
  (0, 2)    2
  (2, 2)    7
顺便说一句,

这是转换为csr格式的一步。

(opps-是由列首先排序的lex)


如果我正确地描绘了随机位,则需要每个非零条目,这是同一行的零插条的随机选择。我假设我们不在乎是否有重生。

因此,我们需要将所有行聚在一起。 lil格式

可能会更容易
In [13]: Ml = M.tolil()
In [14]: Ml.data
Out[14]: array([[1, 2], [8, 4], [6, 7]], dtype=object)
In [16]: Ml.rows
Out[16]: array([[0, 2], [0, 1], [1, 2]], dtype=object)

仅在Ml.rows中的每个列表上迭代并生成随机选择。


这是一个开始:

def foo(cols, N):
    c = set(range(N))
    c = c.difference(cols)
    return np.random.choice(list(c))
In [29]: [foo(c,3) for c in Ml.rows]
Out[29]: [1, 2, 0]

不是我们想要的;它为每行选择一个零列。在此示例中,每行只有一个。

更改choice以返回每个呼叫的多个值:

def foo(cols, N):
    c = set(range(N))
    c = c.difference(cols)
    return np.random.choice(list(c),size=len(cols), replace=True)
In [32]: [foo(c,3) for c in Ml.rows]
Out[32]: [array([1, 1]), array([2, 2]), array([0, 0])]

我们可以取随机值,将它们写回Ml,为data

In [37]: randval = [foo(c,3) for c in Ml.rows]
In [38]: randval
Out[38]: [array([1, 1]), array([2, 2]), array([0, 0])]
In [39]: Ml.data
Out[39]: array([[1, 2], [8, 4], [6, 7]], dtype=object)
In [40]: Ml.data[:] = randval
In [41]: Ml.data
Out[41]: array([array([1, 1]), array([2, 2]), array([0, 0])], dtype=object)
In [42]: Ml.A
Out[42]: 
array([[1, 0, 1],
       [2, 2, 0],
       [0, 0, 0]], dtype=int32)
In [45]: print(Ml)
  (0, 0)    1
  (0, 2)    1
  (1, 0)    2
  (1, 1)    2
  (2, 1)    0
  (2, 2)    0
In [48]: Mo=Ml.tocoo()
In [51]: np.column_stack((Mo.row, Mo.col, Mo.data))
Out[51]: 
array([[0, 0, 1],
       [0, 2, 1],
       [1, 0, 2],
       [1, 1, 2],
       [2, 1, 0],
       [2, 2, 0]], dtype=int32)

如果数组较大,每行多个零列更大,则此显示更有意义。另外,如果任何行密集(没有零),我的代码将破坏。

所以一起

In [56]: M=sparse.rand(10,10,.2,'coo')
In [58]: Ml=M.tolil()
In [59]: randval = [foo(c,Ml.shape[1]) for c in Ml.rows]
In [61]: Ml.data[:] = randval
In [62]: Mo=Ml.tocoo()
In [63]: np.column_stack((Mo.row, Mo.col, Mo.data))

从您的评论中复制,以便于格式化

最初,我有此功能:

def get_triplets(M): 
   return M.row, M.col, np.random.randint(M.shape[1], size=len(M.row))

它及时起作用,但不一致。但是现在:

def get_triplets(mat): 
     M1 = mat.tolil() 
     randval = [foo(c, M1.shape[1]) for c in M1.rows] 
     M1.data[:] = randval 
     Mo = M1.tocoo() 
     return_mat = np.column_stack((Mo.row, Mo.col, Mo.data)) 
     return return_mat[:, 0], return_mat[:, 1], return_mat[:, 2] 

相关内容

最新更新