好吧,它增加了賦值語句的數量,但是在大圖中懲罰是多少?
lil
是索引賦值最有效的格式,但我在其他文章的替代方案中進行了探索。如果我沒有記錯的話,直接分配到data
和rows
屬性的lil
會更快,儘管這在一次填充整行時主要是有價值的。
一個dok
也比較快,但我發現,分配到一個普通的字典,然後更新到dok
也較快。 (A dok
是一個字典子類)。
但是如果你去了coo
路線 - 的data
,rows
和cols
價值的樓宇名單,創造既i,j
和j,i
而言,一旦成本不高。如果你可以一次定義一堆值,那更好,而不是迭代所有的i,j
。
因此,高效地創建對稱矩陣只是有效矩陣定義問題的一個子集。
我不知道稀疏包中有任何對稱化函數。我不知道任何線性代數函數是否有對稱規定。我懷疑最有效的處理程序只是假設矩陣是上或下三角形,沒有明確的對稱值。
您可能會創建一個上三角矩陣,然後將這些值複製到下方。在密集的情況下,最簡單的方法是對矩陣和它的轉置進行求和(並且可能減去對角線)。但稀疏矩陣求和有點高效,所以可能不是最好的。但我沒有做任何測試。
============
轉置的總和ATLEAST沒有給我任何的警告效率:轉置的
In [383]: M=sparse.lil_matrix((10,10),dtype=int)
In [384]:
In [384]: for i in range(10):
...: for j in range(i,10):
...: v=np.random.randint(0,10)
...: if v>5:
...: M[i,j]=v
...:
In [385]: M
Out[385]:
<10x10 sparse matrix of type '<class 'numpy.int32'>'
with 22 stored elements in LInked List format>
In [386]: M.A
Out[386]:
array([[0, 7, 7, 0, 9, 0, 7, 0, 0, 9],
[0, 0, 7, 8, 0, 8, 0, 0, 9, 0],
[0, 0, 0, 7, 0, 0, 9, 0, 8, 0],
[0, 0, 0, 0, 0, 0, 6, 0, 6, 6],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 8, 9, 0, 8],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 8, 8],
[0, 0, 0, 0, 0, 0, 0, 0, 6, 8],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
款項(減去重複的對角線):
In [389]: M+M.T-sparse.diags(M.diagonal(),dtype=int)
Out[389]:
<10x10 sparse matrix of type '<class 'numpy.int32'>'
with 43 stored elements in Compressed Sparse Row format>
In [390]: _.A
Out[390]:
array([[0, 7, 7, 0, 9, 0, 7, 0, 0, 9],
[7, 0, 7, 8, 0, 8, 0, 0, 9, 0],
[7, 7, 0, 7, 0, 0, 9, 0, 8, 0],
[0, 8, 7, 0, 0, 0, 6, 0, 6, 6],
[9, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 8, 0, 0, 0, 0, 8, 9, 0, 8],
[7, 0, 9, 6, 0, 8, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 9, 0, 0, 8, 8],
[0, 9, 8, 6, 0, 0, 0, 8, 6, 8],
[9, 0, 0, 6, 0, 8, 0, 8, 8, 0]], dtype=int32)
雙重分配辦法:
In [391]: M=sparse.lil_matrix((10,10),dtype=int)
In [392]: for i in range(10):
...: for j in range(i,10):
...: v=np.random.randint(0,10)
...: if v>5:
...: M[i,j]=v
...: M[j,i]=v
我沒有做過任何計時。
甲coo
方法:
In [398]: data,rows,cols=[],[],[]
In [399]: for i in range(10):
...: for j in range(i,10):
...: v=np.random.randint(0,10)
...: if v>5:
...: if i==j:
...: # prevent diagonal duplication
...: data.append(v)
...: rows.append(i)
...: cols.append(j)
...: else:
...: data.extend((v,v))
...: rows.extend((i,j))
...: cols.extend((j,i))
...:
In [400]: sparse.coo_matrix((data,(rows,cols)),shape=(10,10)).A
Out[400]:
array([[0, 8, 0, 6, 8, 9, 9, 0, 0, 0],
[8, 7, 0, 0, 0, 6, 0, 8, 0, 0],
[0, 0, 0, 0, 0, 0, 9, 9, 7, 9],
[6, 0, 0, 0, 7, 0, 0, 0, 0, 6],
[8, 0, 0, 7, 0, 0, 8, 0, 0, 0],
[9, 6, 0, 0, 0, 0, 6, 0, 0, 0],
[9, 0, 9, 0, 8, 6, 8, 0, 0, 0],
[0, 8, 9, 0, 0, 0, 0, 6, 0, 6],
[0, 0, 7, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 9, 6, 0, 0, 0, 6, 0, 9]])
===============
它可能快一點,使上三COO矩陣,並延伸到下用列表(或陣列)級聯
In [401]: data,rows,cols=[],[],[]
In [402]: for i in range(10):
...: for j in range(i,10):
...: v=np.random.randint(0,10)
...: if v>5:
...: data.append(v)
...: rows.append(i)
...: cols.append(j)
In [408]: sparse.coo_matrix((data,(rows,cols)),shape=(10,10)).A
Out[408]:
array([[8, 0, 0, 9, 8, 7, 0, 7, 9, 0],
[0, 7, 6, 0, 0, 7, 0, 0, 9, 0],
[0, 0, 9, 8, 0, 9, 6, 0, 0, 6],
...]])
In [409]: data1=data+data
In [410]: rows1=rows+cols
In [411]: cols1=cols+rows
In [412]: sparse.coo_matrix((data1,(rows1,cols1)),shape=(10,10)).A
這複製了對角線,這是我需要以某種方式或其他(重複COO指數求和)來解決。但它提供瞭如何將樣式輸入收集到較大的塊中的想法。