我有一些构成scipy.coo_matrix
的索引和值。索引/值是从不同的子程序生成的,并且在移交给矩阵构造函数之前是concatenate
d:
import numpy
from scipy import sparse
n = 100000
I0 = range(n)
J0 = range(n)
V0 = numpy.random.rand(n)
I1 = range(n)
J1 = range(n)
V1 = numpy.random.rand(n)
# [...]
I = numpy.concatenate([I0, I1])
J = numpy.concatenate([J0, J1])
V = numpy.concatenate([V0, V1])
matrix = sparse.coo_matrix((V, (I, J)), shape=(n, n))
现在,(I, J, V)
的组件可能非常大,因此连接操作变得非常重要。 (在上面的示例中,它占用了我机器上20%的运行时间。)I'm reading that it's not possible to concatenate without a copy。
有没有办法在不先复制输入数据的情况下移交索引和值?
答案 0 :(得分:1)
如果您查看coo_matrix.__init__
的代码,您会发现它非常简单。实际上,如果(V, (I,J))
输入正确,则只需将这3个数组分配给其.data
,row
,col
属性。您甚至可以在创建后通过将这些属性与变量进行比较来检查它。
如果他们不是正确dtype的1d阵列,它会按摩它们 - 制作阵列等等。因此,如果没有详细说明,您事先处理可能会节省coo
的时间调用
self.row = np.array(row, copy=copy, dtype=idx_dtype)
self.col = np.array(col, copy=copy, dtype=idx_dtype)
self.data = np.array(obj, copy=copy)
这些属性的一种或另外一种方法都必须是单个数组,而不是松散的数组列表或列表列表。
sparse.bmat
从其他矩阵中生成coo
矩阵。它收集了coo
个属性,将它们加入fill an empty array
个样式,然后调用coo_matrix
。看看它的代码。
几乎所有返回新数组的numpy
操作都是通过分配empty
并填充它来完成的。让numpy在编译代码(使用np.concatentate
)中执行此操作应该会快一点,但是输入的大小和数量等细节会有所不同。
non_connonical
coo
矩阵才刚刚开始。许多操作都需要转换为其他格式之一。
Efficiently construct FEM/FVM matrix
这是关于稀疏矩阵构造,其中有许多需要求和的重复点 - 并使用csr
格式进行计算。
答案 1 :(得分:0)
您可以尝试预先分配数组。它至少可以免除你的副本。我没有看到这个例子的任何加速,但你可能会看到一个变化。
import numpy
from scipy import sparse
n = 100000
I = np.empty(2*n, np.double)
J = np.empty_like(I)
V = np.empty_like(I)
I[:n] = range(n)
J[:n] = range(n)
V[:n] = numpy.random.rand(n)
I[n:] = range(n)
J[n:] = range(n)
V[n:] = numpy.random.rand(n)
matrix = sparse.coo_matrix((V, (I, J)), shape=(n, n))