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

stszievb  于 2023-11-19  发布在  其他
关注(0)|答案(2)|浏览(90)

给出:

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数组。
什么是简单和内存高效的方法来扁平化或挤压scipy稀疏lil_matrix

bq9c1y66

bq9c1y661#

像lil_matrix这样的稀疏矩阵只适用于2维Tensor,所以将其展平到一维是没有意义的。因此,它并不真正受支持。你在下游的用法是什么?
我建议将其重新整形为一行,并沿着该行查询其条目:

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

字符串

a11xaf1n

a11xaf1n2#

一个更温和的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矩阵。因为你发现它没有flatten方法。你在lil文档中找到了getrowview,但你没有找到flatten,是吗?阅读实际文档,而不是你的愿望。

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


同样从文档中,你可以看到lil有两个属性,datarows,两个对象都包含列表:

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


lil是唯一的,因为它可以得到一个view(在ndarray意义上)的行。其他稀疏格式没有。例如,没有columnview
外部对象数组表示row层,内部列表是列。稀疏数组没有一维表示。
但是为什么你想要一个flatten。稀疏矩阵,在np.matrix的模式中只有2d,所以flatten并不意味着什么。
为了强调这一点,
二维密集阵列:

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


1d:

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


二维密集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)


A np.matrix“捷径”:

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


scipy中有一个转换为类似数组的对象的动作,例如lil_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

相关问题