在 scipy 稀疏矩阵中直接设置数据成员
Set directly data members in scipy sparse matrix
我正在构建一个大型 CSR 稀疏矩阵,即使在稀疏格式下也会使用相当多的内存,因此我想在创建矩阵时避免复制。我发现最有效的方法是直接构建压缩的稀疏行表示。然而,class 初始化程序复制了我传递给它的数组,所以我直接设置了数据成员。示例:
from scipy import sparse
m = sparse.csr_matrix((5,5))
m.data = np.arange(5)
m.indices = np.arange(5)
m.indptr = np.arange(6)
这似乎有效,但我没有在文档中找到它,我想知道它是否受支持,如果它破坏了我没有尝试过的东西。
此外,了解我是否可以毫无怪癖地使用内存映射数组,或者对索引使用不同的整数数据类型,这将很有用。
编辑:
接受的答案表明,如果索引类型正确,则不会发生任何复制。我已经检查了 __init__
,即使它不复制 indices
和 indptr
,它也会扫描两次以找到最小值和最大值,并且它有效地做到了如果输入格式正确,无非就是设置 data
、indices
和 indptr
成员,所以为了性能,我现在正在做的是:
# [...] get shape and data from somewhere
m = sparse.csr_matrix(shape, dtype=data.dtype)
indices = np.empty(..., dtype=m.indices.dtype)
indptr = np.empty(..., dtype=m.indptr.dtype)
# [...] fill indices and indptr
m.data = data
m.indices = indices
m.indptr = indptr
# Possibly also do one or both of the following:
m.has_sorted_indices = True
m.has_canonical_format = True
下面是一个在不复制定义数组的情况下创建稀疏矩阵的示例:
In [191]: data=np.arange(5)
...: indices=np.arange(5).astype('int32')
...: indptr=np.arange(6).astype('int32')
In [192]: M = sparse.csr_matrix((data,indices,indptr))
In [193]: data.__array_interface__['data'], M.data.__array_interface__['data']
Out[193]: ((55897168, False), (55897168, False))
In [194]: indices.__array_interface__['data'], M.indices.__array_interface__['data']
Out[194]: ((70189040, False), (70189040, False))
In [195]: indptr.__array_interface__['data'], M.indptr.__array_interface__['data']
Out[195]: ((56184432, False), (56184432, False))
https://github.com/scipy/scipy/blob/v1.4.1/scipy/sparse/compressed.py
我写这篇文章时考虑到了 __init__
。另请查看 check_format
方法以了解它检查的一致性。
我正在构建一个大型 CSR 稀疏矩阵,即使在稀疏格式下也会使用相当多的内存,因此我想在创建矩阵时避免复制。我发现最有效的方法是直接构建压缩的稀疏行表示。然而,class 初始化程序复制了我传递给它的数组,所以我直接设置了数据成员。示例:
from scipy import sparse
m = sparse.csr_matrix((5,5))
m.data = np.arange(5)
m.indices = np.arange(5)
m.indptr = np.arange(6)
这似乎有效,但我没有在文档中找到它,我想知道它是否受支持,如果它破坏了我没有尝试过的东西。
此外,了解我是否可以毫无怪癖地使用内存映射数组,或者对索引使用不同的整数数据类型,这将很有用。
编辑:
接受的答案表明,如果索引类型正确,则不会发生任何复制。我已经检查了 __init__
,即使它不复制 indices
和 indptr
,它也会扫描两次以找到最小值和最大值,并且它有效地做到了如果输入格式正确,无非就是设置 data
、indices
和 indptr
成员,所以为了性能,我现在正在做的是:
# [...] get shape and data from somewhere
m = sparse.csr_matrix(shape, dtype=data.dtype)
indices = np.empty(..., dtype=m.indices.dtype)
indptr = np.empty(..., dtype=m.indptr.dtype)
# [...] fill indices and indptr
m.data = data
m.indices = indices
m.indptr = indptr
# Possibly also do one or both of the following:
m.has_sorted_indices = True
m.has_canonical_format = True
下面是一个在不复制定义数组的情况下创建稀疏矩阵的示例:
In [191]: data=np.arange(5)
...: indices=np.arange(5).astype('int32')
...: indptr=np.arange(6).astype('int32')
In [192]: M = sparse.csr_matrix((data,indices,indptr))
In [193]: data.__array_interface__['data'], M.data.__array_interface__['data']
Out[193]: ((55897168, False), (55897168, False))
In [194]: indices.__array_interface__['data'], M.indices.__array_interface__['data']
Out[194]: ((70189040, False), (70189040, False))
In [195]: indptr.__array_interface__['data'], M.indptr.__array_interface__['data']
Out[195]: ((56184432, False), (56184432, False))
https://github.com/scipy/scipy/blob/v1.4.1/scipy/sparse/compressed.py
我写这篇文章时考虑到了 __init__
。另请查看 check_format
方法以了解它检查的一致性。