2014-08-28 98 views
1

當試圖直接設置稀疏lil_matrixdata屬性時,我遇到了非常意外的行爲。有人可以解釋下面的簡單例子是怎麼回事?稀疏lil_matrix不能分配數據

我特別的用例是我想設置行模2;即在密集矩陣說我只想做matrix[0] %= 2

from scipy import sparse 
import numpy as np 
np.random.seed(0) 

matrix = sparse.rand(10**3,10**3).tolil() 
num_entries = len(matrix[0].data[0]) 
print num_entries 
# 9 

# this throws no errors... 
matrix[0].data[0] = [2]*num_entries 
# but does nothing! 

assert (np.array(matrix[0].data) == 2).all() # FAILS 

# in fact nothing can be done to alter .data directly... 
matrix[0].data[0].pop() # returns the last float from the row 
# but does not actually pop it from the row! 
assert (len(matrix[0].data[0]) == num_entries-1) # FAILS 
+0

'num_entries'的價值是什麼?我猜'0'。 'matrix.data'是列表的列表,而'matrix.data [0]'是其中的第一個。它可能是空的。 – hpaulj 2014-08-28 19:58:33

+0

我在上面的代碼中添加了它 - 但num_entries是9. matrix.data實際上是列表的Python對象的numpy.array。 – gabe 2014-08-28 20:07:27

+1

所以'matrix [i] .data [0] == matrix.data [i]'適用於所有'i',但與'is'運算符相比並非如此。 – hpaulj 2014-08-28 22:08:36

回答

1

我不太知道什麼樣的對象matrix[0]的是,但我想你的意思砸matrix索引,只保持在data

num_entries = len(matrix.data[0]) 
matrix.data[0] = [2]*num_entries 
+1

這解決了它,謝謝!我認爲_reason_是'matrix [0]'實際上是複製第一行並將其放入一個新矩陣中。所以當我設置這些數據時,我沒有設置「矩陣」。 – gabe 2014-08-28 18:37:33

0

@vlsd發現的bug ,但我想說的更多。

與我發佈的代碼的問題是,我分配(遍及)到matrix[0].data。問題是matrix[0]與密集陣列不一樣;它不是簡單地指向同一個對象,而是創建一個新對象(我認爲)。因此,將數據分配給這個新對象是好的,但它不會影響matrix。那就是問題所在。

所以下面的代碼工作正常:

matrix.data[0] = [2]*num_entries 
assert (np.array(matrix.data[0]) == 2).all() # passes 
matrix.data[0].pop() 
assert (len(matrix.data[0]) == num_entries-1) # passes 

NB從列表彈出通常是一個壞主意,因爲這可能破壞了稀疏矩陣的完整性。但這只是爲了演示。現在它是有道理的。