使用scipy.sparse创建大型稀疏矩阵

3

我在我的应用程序中使用scipy.sparse,并希望进行一些性能测试。为了做到这一点,我需要创建一个大的稀疏矩阵(然后在我的应用程序中使用它)。只要矩阵很小,我就可以使用以下命令来创建它:

import scipy.sparse as sp
a = sp.rand(1000,1000,0.01)

这将生成一个1000x1000的矩阵,其中有10.000个非零条目(合理的密度意味着每行大约有10个非零条目)。

问题在于当我尝试创建一个更大的矩阵时,例如一个100,000 x 100,000的矩阵(我以前处理过更大的矩阵),我会遇到问题。

import scipy.sparse as sp
N = 100000
d = 0.0001
a = sp.rand(N, N, d)

当我尝试生成一个100,000×100,000的矩阵,并有一百万个非零元素(完全可行),却出现了错误信息:

Traceback (most recent call last):
  File "<pyshell#6>", line 1, in <module>
    sp.rand(100000,100000,0.0000001)
  File "C:\Python27\lib\site-packages\scipy\sparse\construct.py", line 723, in rand
    j = random_state.randint(mn)
  File "mtrand.pyx", line 935, in mtrand.RandomState.randint (numpy\random\mtrand\mtrand.c:10327)
OverflowError: Python int too large to convert to C long

有一个很烦人的内部scipy错误,我无法解决。


我知道可以通过创建一百个n乘n矩阵,然后将它们堆叠在一起来创建一个10*n乘10*n矩阵,但是我认为scipy.sparse应该能够处理大型稀疏矩阵的创建(我再次强调,100k乘100k绝不算大,而且scipy可以轻松处理具有数百万行的矩阵)。我错过了什么吗?


这可能是因为它通过在0和N*M之间选择一个32位整数来选择随机条目来给出您的矩阵,而最大的32位(有符号)整数是2^31-1100,000*100,000 = 10,000,000,000 > 2,147,483,647 = 2^31-1)。使用bmat分块构建可能是最简单的解决方法。尝试使N*M = 2^31-2,然后是2^31,看看是否会出现问题。 - will
我无法再编辑之前的评论了,但是那个错误与我所描述的一致:Python int too large to convert to C long,并且与 climits 头文件中的限制相符。 - will
这可能只会在32位Python上发生,这也可能是为什么这个错误之前没有被注意到的原因。 - pv.
正如Jan-Philip Gehrcke在下面指出的那样,这取决于系统 - 我认为您应该能够查看您系统中的stdint.h并查看您的限制是什么。 - will
@pv。不,我正在运行64位的Python。 - 5xum
1
我为错误的错误信息打开了一个问题。 (https://github.com/scipy/scipy/issues/4557) - cgohlke
1个回答

3

在解决问题之前,请确保您正在使用 Linux 平台上的 64 位构建和 64 位架构。在那里,本机的“long”数据类型大小为 64 位(相对于 Windows,我认为是这样的)。

参考以下表格:

编辑: 也许我之前没有表述清楚——在64位Windows上,经典的本地“long”数据类型大小为32位(请参见this问题)。这可能是你的情况存在问题的原因。也就是说,当你改变平台到Linux时,你的代码可能会正常工作。我不能绝对确定这一点,因为它确实取决于numpy/scipy C源码中使用了哪些本地数据类型(当然,在Windows上有64位数据类型可用,并且通常会通过编译器指令执行平台案例分析,并通过宏选择适当的类型——我无法想象他们会意外使用32位数据类型)。

编辑2:

我可以提供三个支持我的假设的数据样本。

Debian 64位、Python 2.7.3和SciPy 0.10.1二进制文件来自Debian仓库:

Python 2.7.3 (default, Mar 13 2014, 11:03:55)
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import scipy; print scipy.__version__; import scipy.sparse as s; s.rand(100000, 100000, 0.0001).shape
0.10.1
(100000, 100000)

Windows 7 64位,32位Python构建版本,32位SciPy 0.10.1构建版本,来自ActivePython:

ActivePython 2.7.5.6 (ActiveState Software Inc.) based on
Python 2.7.5 (default, Sep 16 2013, 23:16:52) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import scipy; print scipy.__version__; import scipy.sparse as s; s.rand(100000, 100000, 0.0001).shape
0.10.1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\user\AppData\Roaming\Python\Python27\site-packages\scipy\sparse\construct.py", line 426, in rand
    raise ValueError(msg % np.iinfo(tp).max)
ValueError: Trying to generate a random sparse matrix such as the product of dimensions is
greater than 2147483647 - this is not supported on this machine

Windows 7 64位操作系统,64位ActivePython版本,64位SciPy 0.15.1版本(来自Gohlke,基于MKL构建):

ActivePython 3.4.1.0 (ActiveState Software Inc.) based on
Python 3.4.1 (default, Aug  7 2014, 13:09:27) [MSC v.1600 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import scipy; scipy.__version__; import scipy.sparse as s; s.rand(100000, 100000, 0.0001).shape
'0.15.1'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python34\lib\site-packages\scipy\sparse\construct.py", line 723, in rand
    j = random_state.randint(mn)
  File "mtrand.pyx", line 935, in mtrand.RandomState.randint (numpy\random\mtrand\mtrand.c:10327)
OverflowError: Python int too large to convert to C long

我正在64位Windows 7平台上使用64位Python的64位版本。 - 5xum
由于我没有Linux平台来测试您的假设,所以我只能猜测您是正确的。 - 5xum
此外,在 Windows 上没有官方的 64 位 numpy 构建版本可用 - 你安装了什么?你使用了 http://www.lfd.uci.edu/~gohlke/pythonlibs/#numpy 吗? - Dr. Jan-Philip Gehrcke
是的,我使用了非官方的二进制文件。在过去,它对我来说运行良好。 - 5xum
Gohlke的构建是使用英特尔编译器套件创建的。这种数据类型“混淆”可能是这些编译器的弱点。我不确定其他人(第三方Python发行版)正在使用哪些编译器,但也许您想尝试Enthought或ActiveState或Anaconda Python。它们都带有自己的NumPy构建。其中一个可能没有遭受您观察到的问题。 - Dr. Jan-Philip Gehrcke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接