Python 初始化高维稀疏矩阵

Python 初始化高维稀疏矩阵,python,numpy,scipy,sparse-matrix,Python,Numpy,Scipy,Sparse Matrix,我想使用sklearn初始化300000 x 3000000稀疏矩阵,但它需要内存,就像它不是稀疏矩阵一样: >>> from scipy import sparse >>> sparse.rand(300000,300000,.1) 它给出了错误: MemoryError: Unable to allocate 671. GiB for an array with shape (300000, 300000) and data type float6

我想使用
sklearn
初始化
300000 x 3000000
稀疏矩阵,但它需要内存,就像它不是稀疏矩阵一样:

>>> from scipy import sparse
>>> sparse.rand(300000,300000,.1)   
它给出了错误:

MemoryError: Unable to allocate 671. GiB for an array with shape (300000, 300000) and data type float64
>>> from scipy import sparse
>>> from scipy import sparse
>>> sparse.rand(300000,300000,.000000000001)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File ".../python3.8/site-packages/scipy/sparse/construct.py", line 842, in rand
    return random(m, n, density, format, dtype, random_state)
  File ".../lib/python3.8/site-packages/scipy/sparse/construct.py", line 788, in random
    ind = random_state.choice(mn, size=k, replace=False)
  File "mtrand.pyx", line 980, in numpy.random.mtrand.RandomState.choice
  File "mtrand.pyx", line 4528, in numpy.random.mtrand.RandomState.permutation
MemoryError: Unable to allocate 671. GiB for an array with shape (90000000000,) and data type int64
这与使用
numpy
初始化时的错误相同:

np.random.normal(size=[300000, 300000])
即使在密度非常低的情况下,它也会再现错误:

MemoryError: Unable to allocate 671. GiB for an array with shape (300000, 300000) and data type float64
>>> from scipy import sparse
>>> from scipy import sparse
>>> sparse.rand(300000,300000,.000000000001)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File ".../python3.8/site-packages/scipy/sparse/construct.py", line 842, in rand
    return random(m, n, density, format, dtype, random_state)
  File ".../lib/python3.8/site-packages/scipy/sparse/construct.py", line 788, in random
    ind = random_state.choice(mn, size=k, replace=False)
  File "mtrand.pyx", line 980, in numpy.random.mtrand.RandomState.choice
  File "mtrand.pyx", line 4528, in numpy.random.mtrand.RandomState.permutation
MemoryError: Unable to allocate 671. GiB for an array with shape (90000000000,) and data type int64
>>从scipy导入稀疏
>>>从scipy导入稀疏
>>>稀疏.rand(300003000000000.000000000001)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“../python3.8/site packages/scipy/sparse/construct.py”,第842行,兰特
返回随机(m、n、密度、格式、数据类型、随机状态)
文件“../lib/python3.8/site packages/scipy/sparse/construct.py”,第788行,随机格式
ind=随机状态。选择(mn,大小=k,替换=False)
文件“mtrand.pyx”,第980行,位于numpy.random.mtrand.RandomState.choice中
文件“mtrand.pyx”,第4528行,位于numpy.random.mtrand.RandomState.permutation中
MemoryError:无法分配671。形状为(9000000000,)且数据类型为int64的数组的GiB

有没有一种更节省内存的方法来创建这样一个稀疏矩阵?

尝试传递一个合理的
密度
参数,如文档中所示。。。如果你有10万亿个细胞,可能是0.00000001之类的


@hpaulj的评论很到位。错误消息中也有一条线索

MemoryError:无法分配671。形状为(9000000000,)且数据类型为int64的数组的GiB

有一个对int64的引用,而不是对float64的引用,以及一个大小为300000 X 300000的线性阵列。这是指创建稀疏矩阵过程中随机采样的中间步骤,该步骤占用大量内存


请注意,在创建任何稀疏矩阵(无论其格式如何)时,必须考虑非零值的内存以及表示矩阵中值的位置的内存。

只需生成所需内容即可

from scipy import sparse
import numpy as np

n, m = 300000, 300000
density = 0.00000001
size = int(n * m * density)

rows = np.random.randint(0, n, size=size)
cols = np.random.randint(0, m, size=size)
data = np.random.rand(size)

arr = sparse.csr_matrix((data, (rows, cols)), shape=(n, m))
这允许您构建怪物稀疏阵列,前提是它们足够稀疏,可以放入内存中

>>> arr
<300000x300000 sparse matrix of type '<class 'numpy.float64'>'
    with 900 stored elements in Compressed Sparse Row format>
>>arr

这可能就是sparse.rand构造函数的工作方式。如果任何一行、列对发生冲突,它将把数据值加在一起,这可能适用于我能想到的所有应用程序。

在哪里指定矩阵填充的密度?据我所知,您正在非备件矩阵上使用备件数据结构。@kpie
density=0.1
sparse.rand
中的第三个参数。即使你选择更少(例如密度=0),它仍然会给出相同的错误
sparse。rand
使用
choice
从300000*300000整数空间生成
k
随机索引。我经常使用这个函数来生成样本稀疏矩阵,但通常只是为了一个合理的测试用例,比如10x10。显然,这并不是用来生成一个非常大的矩阵的方法,不管你把它做得多么稀疏。最终的矩阵不会占用这么多空间,但这种生成索引的方法确实暂时需要它。
scipy.sparse
有多种创建稀疏矩阵的方法。一个常见的on使用3
coo
样式的数组-您可以选择索引和数据值。较慢的方法是从正确形状的
lil
开始,然后“随机”分配元素<代码>稀疏。随机只是创建测试矩阵的一个方便工具,很少用于生产目的。