繁体   English   中英

scipy.sparse矩阵的索引操作的矢量化

[英]Vectorization of index operation for a scipy.sparse matrix

即使一切似乎都是矢量化的,下面的代码运行得太慢了。

from numpy import *
from scipy.sparse import *

n = 100000;
i = xrange(n); j = xrange(n);
data = ones(n);

A=csr_matrix((data,(i,j)));

x = A[i,j]

问题似乎是索引操作是作为python函数实现的,并且调用A[i,j]导致以下分析输出

         500033 function calls in 8.718 CPU seconds

   Ordered by: internal time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
   100000    7.933    0.000    8.156    0.000 csr.py:265(_get_single_element)
        1    0.271    0.271    8.705    8.705 csr.py:177(__getitem__)
(...)

也就是说,python函数_get_single_element被调用100000次,这实在是效率低下。 为什么不在纯C中实现? 有没有人知道解决这个限制的方法,并加快上述代码? 我应该使用不同的稀疏矩阵类型吗?

您可以使用A.diagonal()更快地检索对角线(0.0009秒与我机器上的3.8秒)。 但是,如果您想进行仲裁索引,那么这是一个更复杂的问题,因为您没有使用切片作为索引列表。 _get_single_element函数被调用100000次,因为它只是遍历传递给它的迭代器(i和j)。 切片将是A [30:60,10]或类似的东西。

另外,为了简单起见,我将使用csr_matrix(eye(n,n))制作与迭代器相同的矩阵。

更新:

好的,既然你的问题确实是能够快速访问大量随机元素,我会尽我所能回答你的问题。

  • 为什么不在纯C中实现?

答案很简单:没人接触过它。 从我所看到的Scipy稀疏矩阵模块领域仍有大量工作要做。 在C中实现的一部分是不同稀疏矩阵格式之间的转换。

  • 有没有人知道解决这个限制的方法,并加快上述代码?

您可以尝试实际潜入稀疏矩阵模块并尝试加速它们。 我这样做了,并且当使用csr矩阵尝试使用上面的代码进行随机访问时,能够将时间缩短到不到原来的三分之一。 我必须直接访问_get_single_element并显着减少代码,包括取出绑定检查。

然而,使用lil_matrix仍然更快(尽管初始化矩阵的速度较慢),但我不得不使用列表解析进行访问,因为没有为您正在进行的索引类型设置lil矩阵。 使用csr_matrix的列表推导仍然使lil矩阵方法顺便前进。 最终,lil矩阵更快地访问随机元素,因为它没有被压缩。

使用原始形式的lil_matrix运行的时间大约是上面列出的代码的五分之一。 如果我取出一些绑定的检查并直接调用lil_matrix的_get1()方法,我可以将时间进一步缩短约原始时间的7%。 为了清楚起见,速度从3.4-3.8秒增加到大约0.261秒。

最后,我尝试创建自己的函数,直接访问lil矩阵的数据,避免重复的函数调用。 这个时间约为0.136秒。 这没有利用被排序的数据,这是另一种潜在的优化(特别是如果您访问同一行上的许多元素)。

如果你想要比那更快,你可能必须编写自己的C代码稀疏矩阵实现。

  • 我应该使用不同的稀疏矩阵类型吗?

好吧,如果你打算访问很多元素,我建议使用lil矩阵,但这完全取决于你需要做什么。 例如,你还需要乘以矩阵吗? 请记住,矩阵之间的更改至少有时(在某些情况下)非常快,因此不排除更改为不同的矩阵格式以执行不同的操作。

如果您不需要在矩阵上进行任何代数运算,那么也许您应该使用defaultdict或类似的东西。 defaultdicts的危险在于,每当要求一个元素不在dict中时,它会将该项设置为默认值并存储它以便可能出现问题。

我认为只有在使用'object'的默认dtype时才会调用_get_single_element。 您是否尝试过提供csr_matrix((data, (i,j)), dtype=int32) ,例如csr_matrix((data, (i,j)), dtype=int32)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM