coo_matrix没有连接

时间:2017-02-27 12:51:30

标签: python numpy scipy

我有一些构成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

有没有办法在不先复制输入数据的情况下移交索引和值?

2 个答案:

答案 0 :(得分:1)

如果您查看coo_matrix.__init__的代码,您会发现它非常简单。实际上,如果(V, (I,J))输入正确,则只需将这3个数组分配给其.datarowcol属性。您甚至可以在创建后通过将这些属性与变量进行比较来检查它。

如果他们不是正确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))