我是Python的新手,这似乎很幼稚。我正在与COO_MATRIX(SCIPY稀疏矩阵) M 一起返回M:
row_index,column_index,random_index
有以下条件:
- row_index,column_index必须指向m 的非零条目
- row_index,column_index与所有非零条目相对应
- 对于每对ROW_INDEX,column_index,Random_index的 应
- Random_index应在m 的[0,total_num_columns]的范围内
- 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矩阵M
,M.row
,M.col
和M.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]