展平 SciPy lil_matrix而不转换为密集以避免内存错误

Flatten SciPy lil_matrix without converting to dense to avoid memory error

提问人:doplano 提问时间:10/31/2023 最后编辑:doplano 更新时间:11/3/2023 访问量:52

问:

鉴于:

import numpy as np
import scipy
print(np.__version__, scipy.__version__) # numpy: 1.23.5 scipy: 1.11.3

我想展平或压缩我的切片数组而不将其转换为密集,以避免内存错误:

mtx=scipy.sparse.lil_matrix((int(2e8), int(4e9)), dtype=np.float32) # very large lil_matrix
mtx[:int(4e6), :int(7e4)]=np.random.rand(int(4e6), int(7e4))
flat_mtx=mtx.getrowview(0).flatten() # sliced example: row: 0

但是我收到以下错误:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'lil_matrix' object has no attribute 'flatten'

对于较小的尺寸,我可以选择或采用更快的方法,但对于较大的尺寸,我不想转换为密集数组。mtx.getrowview(0).toarray().flatten()np.squeeze(sp_mtx.getrowview(0).toarray())numpy

展平或压缩稀疏的简单且内存高效的方法是什么?scipylil_matrix

python scipy 稀疏矩阵 展平

评论


答:

2赞 Learning is a mess 10/31/2023 #1

像 lil_matrix 这样的稀疏矩阵仅适用于二维张量,因此将其展平为单维是没有意义的。因此,它没有得到真正的支持。您的下游使用情况如何?

我建议将其重新调整为一行,并沿着该行查询其条目:

flat_mtx = mtx.reshape([1,-1])
first_entry, last_entry = flat_mtx[0,0], flat_mtx[0,-1]

评论

0赞 hpaulj 10/31/2023
getrowview应该已经是 1 行了。
0赞 hpaulj 11/1/2023 #2

一个更适度的 lil 矩阵:

In [245]: mtx = scipy.sparse.lil_matrix((10,10), dtype=np.float32)     
In [246]: mtx
Out[246]: 
<10x10 sparse matrix of type '<class 'numpy.float32'>'
    with 0 stored elements in List of Lists format>

In [248]: arow = mtx.getrowview(0)    
In [249]: arow
Out[249]: 
<1x10 sparse matrix of type '<class 'numpy.float32'>'
    with 0 stored elements in List of Lists format>

这仍然是一个 lil 矩阵。正如你所发现的,它没有方法。你在文档中找到了,但你没有找到,是吗?阅读实际文档,而不是您的意愿。flattengetrowviewlilflatten

In [250]: arow.flatten
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[250], line 1
----> 1 arow.flatten

File ~\miniconda3\lib\site-packages\scipy\sparse\_base.py:771, in spmatrix.__getattr__(self, attr)
    769     return self.getnnz()
    770 else:
--> 771     raise AttributeError(attr + " not found")

AttributeError: flatten not found

同样从文档中,您可以看到它有 2 个属性,以及 ,这两个对象 dtype 数组都包含列表:lildatarows

In [251]: arow.data, arow.rows
Out[251]: (array([list([])], dtype=object), array([list([])], dtype=object))

该格式的独特之处在于可以获取行的(在ndarray意义上)。其他稀疏格式则不然。例如,没有 .lilviewcolumnview

外部对象数组表示图层,内部列表表示列。稀疏数组没有一维表示形式。row

但是你为什么想要一个.稀疏矩阵,在模式中只有 2d,所以扁平化没有任何意义。flattennp.matrix

说到这里,

2D 密集阵列:

In [253]: arow.toarray()
Out[253]: array([[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]], dtype=float32)

1天:

In [254]: arow.toarray().flatten()
Out[254]: array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], dtype=float32)

2d 密集 :matrix

In [255]: arow.todense()
Out[255]: matrix([[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]], dtype=float32)

静态 2D:

In [256]: arow.todense().flatten()
Out[256]: matrix([[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]], dtype=float32)

“捷径”:np.matrix

In [257]: arow.todense().A1
Out[257]: array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], dtype=float32)

有一个移动到像数组一样的对象,例如,但这仍然是一项正在进行的工作。scipylil_array

In [259]: atx = scipy.sparse.lil_array(mtx)

In [260]: atx
Out[260]: 
<10x10 sparse array of type '<class 'numpy.float32'>'
    with 0 stored elements in List of Lists format>

In [261]: atx.getrowview(0)
Out[261]: 
<1x10 sparse array of type '<class 'numpy.float32'>'
    with 0 stored elements in List of Lists format>

还是没有.flatten