Python int8 scipy稀疏矩阵创建错误创建int64结构?
我一直在尝试使用scipy.sparse创建一个非常大的方形矩阵,其中左下半部分为零,右上半部分为一。我使用了dtypePython int8 scipy稀疏矩阵创建错误创建int64结构?,python,python-3.x,numpy,matrix,scipy,Python,Python 3.x,Numpy,Matrix,Scipy,我一直在尝试使用scipy.sparse创建一个非常大的方形矩阵,其中左下半部分为零,右上半部分为一。我使用了dtypeint8来表示每个元素(看起来使用布尔值会导致8位存储,所以使用它没有意义) 对于相当大的矩阵(比如16300x16300),下面描述的两种方法都很有效 为此,我尝试了各种方法来创建一个,然后使用triu创建一个三角形 问题是,当我尝试生成一个数组(比如522659x522659)时,这些数组被正确创建,但是triu失败,出现以下错误 注意我有750gb的内存,其中4gb在执行
int8
来表示每个元素(看起来使用布尔值会导致8位存储,所以使用它没有意义)
对于相当大的矩阵(比如16300x16300),下面描述的两种方法都很有效
为此,我尝试了各种方法来创建一个,然后使用triu
创建一个三角形
问题是,当我尝试生成一个数组(比如522659x522659)时,这些数组被正确创建,但是triu
失败,出现以下错误
注意我有750gb的内存,其中4gb在执行前使用。所以内存错误是真的,因为我无法创建2或4tb的数组!但问题是,我不需要像这样大小的分配来将我想要的数字存储为单个字节
我的问题是:
int64
类型的对象,而我已经将int8
类型的数据提供给它scipy.sparse.triu
的过程中,而不是在生成值的过程中
Python 3.5.4 (default, Sep 27 2019, 09:11:05)
[GCC 7.4.0] on linux
numpy==1.18.0
scipy==1.4.1
尝试2:
这一次创建的内存占用约134gb,但当将这些内存添加到矩阵中时,内存使用量将继续攀升至约387gb,并保持不变,然后以与尝试1类似的方式崩溃。请注意,它尝试创建的int64
的大小是尝试1的一半,这是我的意图-只生成我需要的那些,但实际内存使用到这一点更大
#!/usr/local/bin/python3.5
import scipy.sparse as sp
import numpy as np
def generate_sparse_pattern(length):
print("Length:" + str(length))
return sp.triu(np.ones((length,length), dtype=np.int8))
m = generate_sparse_pattern(522659)
这个答案正在进行中 当稀疏矩阵是稀疏矩阵时,它们在空间和时间上都是高效的。粗略的经验表明,10%或更少的稀疏度是好的。50%不是 该软件包的核心是为线性代数工作开发的(例如有限元ODE解决方案)。特别是
csr
格式针对矩阵乘法进行了优化。它使用编译代码(cython
),它使用标准的c
数据类型-整数、浮点和双精度。在numpy
术语中,表示int64
、float32
和float64
。所选格式接受其他数据类型,如int8
,但在转换为其他格式和计算时很难保持该数据类型
行和列索引被显式存储(用于coo
和csr
),并根据矩阵的形状使用int32
或int64
===
您的第一个方法:
#!/usr/local/bin/python3.5
import scipy.sparse as sp
import numpy as np
def generate_sparse_pattern(length):
print("Length:" + str(length))
print("Create Matrix")
matrix = sp.lil_matrix((length,length), dtype=np.int8)
print("Create Ones")
ones = np.ones((length * (length+1) // 2), dtype=np.int8)
matrix[np.triu_indices_from(matrix,0)] = ones
return matrix.tocsr()
m = generate_sparse_pattern(522659)
273172430281是长度**2
,原始数组中的总数。由于形状的原因,它必须使用较大的int64
dtype。密集数组只需要有空间容纳273172430281int8
值,但是稀疏数组添加了这个int64
索引数组triu
将把所有这些数组一分为二(取决于k),但这仍然比密集数组大
===
在第二种情况下
File "/usr/local/lib/python3.5/site-packages/scipy/sparse/extract.py", line 162, in triu
A = coo_matrix(A, copy=False)
File "/usr/local/lib/python3.5/site-packages/scipy/sparse/coo.py", line 191, in __init__
self.row, self.col = M.nonzero()
MemoryError: Unable to allocate 3.98 TiB for an array with shape (273172430281, 2) and data type int64
生成(n,m)布尔掩码
tri(n, m, k=k-1, dtype=bool)
查找该掩码的非零元素的索引。它需要类似的空间
nonzero(~tri(n, m, k=k-1, dtype=bool))
是一个2元素的元组,包含15个元素的行和列索引数组
密集阵列占用的空间要少得多,即使它同时节省了0和1:
(136586476470, 2) and data type int64
In [43]: np.triu_indices_from(np.ones((5,5)))
Out[43]:
(array([0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 4]),
array([0, 1, 2, 3, 4, 1, 2, 3, 4, 2, 3, 4, 3, 4, 4]))
这个答案正在进行中 当稀疏矩阵是稀疏矩阵时,它们在空间和时间上都是高效的。粗略的经验表明,10%或更少的稀疏度是好的。50%不是 该软件包的核心是为线性代数工作开发的(例如有限元ODE解决方案)。特别是
csr
格式针对矩阵乘法进行了优化。它使用编译代码(cython
),它使用标准的c
数据类型-整数、浮点和双精度。在numpy
术语中,表示int64
、float32
和float64
。所选格式接受其他数据类型,如int8
,但在转换为其他格式和计算时很难保持该数据类型
行和列索引被显式存储(用于coo
和csr
),并根据矩阵的形状使用int32
或int64
===
您的第一个方法:
#!/usr/local/bin/python3.5
import scipy.sparse as sp
import numpy as np
def generate_sparse_pattern(length):
print("Length:" + str(length))
print("Create Matrix")
matrix = sp.lil_matrix((length,length), dtype=np.int8)
print("Create Ones")
ones = np.ones((length * (length+1) // 2), dtype=np.int8)
matrix[np.triu_indices_from(matrix,0)] = ones
return matrix.tocsr()
m = generate_sparse_pattern(522659)
273172430281是长度**2
,原始数组中的总数。由于形状的原因,它必须使用较大的int64
dtype。密集数组只需要有空间容纳273172430281int8
值,但是稀疏数组添加了这个int64
索引数组triu
将把所有这些数组一分为二(取决于k),但这仍然比密集数组大
===
在第二种情况下
File "/usr/local/lib/python3.5/site-packages/scipy/sparse/extract.py", line 162, in triu
A = coo_matrix(A, copy=False)
File "/usr/local/lib/python3.5/site-packages/scipy/sparse/coo.py", line 191, in __init__
self.row, self.col = M.nonzero()
MemoryError: Unable to allocate 3.98 TiB for an array with shape (273172430281, 2) and data type int64
生成(n,m)布尔掩码
tri(n, m, k=k-1, dtype=bool)
查找该掩码的非零元素的索引。它需要类似的空间
nonzero(~tri(n, m, k=k-1, dtype=bool))
是一个2元素的元组,包含15个元素的行和列索引数组
密集阵列占用的空间要少得多,即使它同时节省了0和1:
(136586476470, 2) and data type int64
In [43]: np.triu_indices_from(np.ones((5,5)))
Out[43]:
(array([0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 4]),
array([0, 1, 2, 3, 4, 1, 2, 3, 4, 2, 3, 4, 3, 4, 4]))
查看
sp.triu
的代码。我从来没用过。在第二个例子中,np.triu
正在创建一个包含所有上层索引的非常大的数组。np.triu index\u from
调用np.tri
来创建一个掩码(这是我想要的!)-但是m中的min\u int
等于更大的外部(arange(N,dtype=\u min\u int(0,N)