Создание большой разреженной матрицы в scipy.sparse
Я использую scipy.sparse
в моем приложении и хочу сделать несколько тестов производительности. Для этого мне нужно создать большую разреженную матрицу (которую я затем буду использовать в своем приложении). Пока матрица мала, я могу создать ее с помощью команды
import scipy.sparse as sp
a = sp.rand(1000,1000,0.01)
В результате получается матрица 1000 на 1000 с 10.000 ненулевых записей (разумная плотность означает примерно 10 ненулевых записей на строку)
Проблема в том, что, когда я пытаюсь создать матрицу большего размера, например, матрицу 100.000 на 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
Я не могу удалить ошибку.
Я понимаю, что могу создать матрицу 10*n на 10*n, создавая матрицы размером сто n на n, а затем сложить их вместе, однако я думаю, что scipy.sparse
должен быть в состоянии справиться с созданием больших разреженных матриц (я еще раз говорю, 100k на 100k ни в коем случае не большой, и scipy
это более чем удобная обработка матриц с несколькими миллионами строк). Я что-то пропустил?
1 ответ
Не углубляясь в суть проблемы, вы должны убедиться, что вы используете 64-битную сборку на 64-битной архитектуре на платформе Linux. Там собственный "длинный" тип данных имеет 64-битный размер (в отличие от Windows, я считаю).
Для справки смотрите эти таблицы:
- http://www.unix.org/whitepapers/64bit.html (-> длинная - 64-битная на LP64)
- http://en.wikipedia.org/wiki/64-bit_computing
Редактировать: Возможно, я не был достаточно ясен раньше - в 64-битной Windows классический тип данных "long" имеет 32-битный размер (также см. Этот вопрос). Это может быть проблемой в вашем случае. То есть ваш код может просто работать, когда вы меняете платформу на Linux. Я не могу сказать это с абсолютной уверенностью, потому что это действительно зависит от того, какие нативные типы данных используются в источнике C Numpy / Scipy (конечно, в Windows доступно 64-битные типы данных, и обычно анализ случая платформы выполняется с помощью директив компилятора и правильные типы выбираются с помощью макросов - я не могу себе представить, что они случайно использовали 32-битные типы данных).
Изменить 2:
Я могу предоставить три образца данных, подтверждающих мою гипотезу.
64-битные Debian, 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)
64-битная Windows 7, 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
64-битная Windows 7, 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