【问题标题】:sparse lil_matrix cannot assign data稀疏 lil_matrix 无法分配数据
【发布时间】:2014-08-29 04:11:28
【问题描述】:

当尝试直接设置稀疏lil_matrixdata 属性时,我遇到了非常意外的行为。有人可以解释以下简单示例中发生了什么吗?

我的特殊用例是我想设置行模 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

【问题讨论】:

  • num_entries 的值是多少?我猜0matrix.data 是列表列表,matrix.data[0] 是其中的第一个。它很可能是空的。
  • 我在上面的代码中添加了它——但是 num_entries 是 9。matrix.data 实际上是一个 numpy.array 的 Python 对象,它们是列表。
  • 所以matrix[i].data[0] == matrix.data[i] 对所有i 都是正确的,但与is 运算符相比,情况并非如此。

标签: python scipy sparse-matrix


【解决方案1】:

我不太确定matrix[0] 是什么类型的对象,但我认为您的意思是删除matrix 上的索引,只保留data 上的索引:

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

【讨论】:

  • 这解决了,谢谢!我认为 原因matrix[0] 实际上是复制第一行并将其放入新矩阵中。所以当我设置数据时,我没有设置matrix
【解决方案2】:

@vlsd 发现了这个错误,但我添加这个是为了说更多。

我发布的代码的问题是我(整个)分配给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 从列表中弹出通常是一个坏主意,因为这可能会破坏稀疏矩阵的完整性。但这只是为了演示。现在它是有道理的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-09-26
    • 2018-09-26
    • 2022-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-15
    相关资源
    最近更新 更多