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
フォーマットへの変換に向かってのステップです。
(中にエラー - それは最初の列でLEXソートされている)
私が正しくランダムビットを描く場合、あなたは、各非ゼロエントリのためのゼロスロットからランダムな選択をしたいです同じ行私は、退職者がいるかどうかは気にしないと思います。
したがって、すべての行をまとめて圧縮する必要があります。 これは単なるMl.rows
に各リストに反復してランダムな選択を生成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)
と簡単になります。
はここでスタートだ:
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]
ない、非常に私たちが何をしたいです。各行に対してゼロ列を選択します。この例では、行ごとに1つしかありません。呼び出しごとに複数の値を返すために
変更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)
にそれらを書くこの表示がより有意義になります1行につき複数のゼロ列で大きくなった。また、いずれかの行が密な場合(ゼロ以外)は、私のコードが壊れます。
だから、すべて一緒にあなたのコメントからコピー
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]
ありがとうございました詳細な明確な答えをありがとうございます。 – Learner
関数で確認するには:return_mat = np.column_stack((Mo.row、Mo.col、Mo.data))return return_mat [:, 0]、return_mat [:, 1]、return_mat [:, 2] ' – Learner
しかし、この操作は非常に時間がかかるようです。あなたが知っているこれを行うための最適な方法はありますか?私は別の質問をするべきですか? – Learner