【问题标题】:Creating a large sparse matrix in scipy.sparse在 scipy.sparse 中创建一个大的稀疏矩阵
【发布时间】:2015-04-25 22:38:07
【问题描述】:

我在我的应用程序中使用scipy.sparse 并想做一些性能测试。为此,我需要创建一个大型稀疏矩阵(然后我将在我的应用程序中使用它)。只要矩阵很小,我可以使用命令创建它

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

这会产生一个 1000 x 1000 的矩阵,其中包含 10.000 个非零条目(合理的密度意味着每行大约有 10 个非零条目)

问题是当我尝试创建一个更大的矩阵时,例如,一个 100.000 x 100.000 的矩阵(我之前处理过 way 个更大的矩阵),我运行

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

这应该会产生一个 100.000 x 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 x n 矩阵然后将它们堆叠在一起来创建一个 10*n x 10*n 矩阵,但是,我认为scipy.sparse 应该能够处理大型稀疏矩阵的创建(我再说一遍,100k x 100k 绝不是大的,scipy 可以轻松地处理数百万行的矩阵)。我错过了什么吗?

【问题讨论】:

  • 这可能是因为它通过选择介于 0 和 N*M 之间的 32 bit int 和最大 32 位(有符号)整数来选择 随机 条目来提供矩阵是2^31-1 (100,000*100,000 = 10,000,000,000 &gt; 2,147,483,647 = 2^31-1)。使用bmat 在块中构建它可能是最简单的解决方法。尝试制作N*M = 2^31-2 然后2^31 看看是否会导致问题弹出。
  • 我无法再编辑之前的评论,但该错误与我所描述的一致:Python int too large to convert to C longclimits 标头中的限制。
  • 这可能只发生在 32 位 Python 上,这可能就是为什么之前没有注意到这个错误。
  • 正如 Jan-Philip Gehrcke 在下面指出的那样,它取决于系统 - 我认为您应该能够在您的系统上查看 stdint.h 并查看您的限制。

标签: python numpy matrix scipy sparse-matrix


【解决方案1】:

在没有深入了解问题的情况下,您应该确保在 Linux 平台上使用基于 64 位架构的 64 位构建。在那里,本机“长”数据类型是 64 位大小(我相信与 Windows 不同)。

有关参考,请参阅以下表格:

编辑: 也许我之前不够明确——在 64 位 Windows 上,经典的本机“长”数据类型是 32 位大小(另见this 问题)。这可能在您的情况下是个问题。也就是说,当您将平台更改为 Linux 时,您的代码可能会正常工作。我不能绝对肯定地说,因为这实际上取决于 numpy/scipy C 源代码中使用了哪些本机数据类型(当然 Windows 上有 64 位数据类型可用,并且通常使用编译器指令执行平台案例分析, 并通过宏选择正确的类型——我真的无法想象他们偶然使用了 32 位数据类型)。

编辑 2:

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

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

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 位版本的 64 位 Python。
  • 由于我没有 Linux 平台来测试您的假设,我只能猜测您是正确的
  • 另外,没有可用于 Windows 的官方 64 位 numpy 版本——实际上你安装了什么?你用lfd.uci.edu/~gohlke/pythonlibs/#numpy了吗?
  • 是的,我使用了非官方的二进制文件。过去它对我很有效。
  • Gohlke 的构建是使用英特尔的编译器套件创建的。 可能这种数据类型“混淆”是这些编译器的弱点。我不确定其他人(第三方 Python 发行版)正在使用哪些编译器,但也许您想尝试 Enthought 或 ActiveState 或 Anaconda Python。他们都带来了自己构建的 NumPy。可能是其中之一没有受到您所观察到的影响。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-05
  • 2012-01-10
  • 2021-09-22
  • 2014-06-16
  • 2018-01-14
  • 2019-05-06
  • 2017-03-31
相关资源
最近更新 更多