我正在做一个项目,我需要处理三维大数组。我使用numpy 3d数组,但我的大多数条目将为零,所以它是大量的内存浪费。Scipy稀疏似乎只允许2D矩阵。有没有其他方法可以存储3D稀疏数组?
14ifxucb1#
scipy.sparse有许多格式,但只有少数格式具有高效的数值运算集,不幸的是,这些格式更难扩展。dok使用索引的元组作为字典键。因此,这很容易从2d泛化到3d或更多。coo有row、col、data属性数组。从概念上讲,添加第三个depth(?)很容易。lil可能需要列表中的列表,这可能会变得混乱。但是csr和csc将数组存储在indices、indptr和data数组中,这种格式是多年前由研究线性代数问题的数学家沿着高效的数学运算(特别是矩阵乘法)而设计出来的(源代码中引用了相关论文)。因此,表示3d稀疏阵列不是问题,但实现高效的矢量运算可能需要一些基础数学研究。你真的需要3d布局来做矢量操作吗?你能,比如说,至少暂时地,把2个维度重塑成1个吗?逐元素操作(*,+,-)处理平面数组的数据与处理二维或三维数组的数据一样好。np.tensordot通过将输入重新整形为二维数组并应用np.dot来处理nD矩阵乘法。即使np.einsum用于三维数组,乘积求和通常也只在一对维度上进行(例如“ijk,jl-〉ikl”)3D表示在概念上可能很方便,但我想不出有什么数学运算需要它(而不是2D或1D)。总的来说,我认为重构数组比尝试寻找/实现真正的3d稀疏运算速度更快。
scipy.sparse
dok
coo
row
col
data
depth
lil
csr
csc
indices
indptr
np.tensordot
np.dot
np.einsum
ssgvzors2#
你说得对看起来并没有现成的工具来处理n维稀疏数组。如果你只需要从数组中访问元素,可以选择使用元组键控的字典。参见:sparse 3d matrix/array in Python?如果你需要在稀疏的3d矩阵上做运算,那就变得更难了--你可能要自己做一些编码。
vngu2lb83#
参见python库:https://sparse.pydata.org/en/stable/construct.html下面是一个2D的例子-从上面提供的页面复制。但是,它也适用于2个以上的维度。我目前正在使用这个库处理可变数量的维度。只是作为一个小注意:在稀疏矩阵具有多于2维的情况下,不可能转换到已知的SciPy稀疏矩阵。
import sparse coords = [[0, 1, 2, 3, 4], [0, 1, 2, 3, 4]] data = [10, 20, 30, 40, 50] s = sparse.COO(coords, data, shape=(5, 5)) s.todense() array([[10, 0, 0, 0, 0], [ 0, 20, 0, 0, 0], [ 0, 0, 30, 0, 0], [ 0, 0, 0, 40, 0], [ 0, 0, 0, 0, 50]])
e5nqia274#
看看github/sparse或pytorch-documentation/sparse,参见下面代码片段(pytorchone)。
import numpy as np import torch N0,N1,N2 = 3,4,5 np_rng = np.random.default_rng() np0 = np_rng.normal(size=(N0,N1,N2)) * (np_rng.uniform(size=(N0,N1,N2))>0.8) #some fake 3d data index = np.stack(np.nonzero(np0)) #(np,int64,(3,nnz)) value = np0[index[0], index[1], index[2]] #(np,float64,nnz) torch0_coo = torch.sparse_coo_tensor(index, value, (N0,N1,N2)) torch0_coo.shape #(3,4,5) torch0_coo.dtype #float64 torch0_coo.indices() #(torch,int64,(ndim,nnz)) torch0_coo.values() #(torch,float64,nnz)
4条答案
按热度按时间14ifxucb1#
scipy.sparse
有许多格式,但只有少数格式具有高效的数值运算集,不幸的是,这些格式更难扩展。dok
使用索引的元组作为字典键。因此,这很容易从2d泛化到3d或更多。coo
有row
、col
、data
属性数组。从概念上讲,添加第三个depth
(?)很容易。lil
可能需要列表中的列表,这可能会变得混乱。但是
csr
和csc
将数组存储在indices
、indptr
和data
数组中,这种格式是多年前由研究线性代数问题的数学家沿着高效的数学运算(特别是矩阵乘法)而设计出来的(源代码中引用了相关论文)。因此,表示3d稀疏阵列不是问题,但实现高效的矢量运算可能需要一些基础数学研究。
你真的需要3d布局来做矢量操作吗?你能,比如说,至少暂时地,把2个维度重塑成1个吗?
逐元素操作(*,+,-)处理平面数组的数据与处理二维或三维数组的数据一样好。
np.tensordot
通过将输入重新整形为二维数组并应用np.dot
来处理nD矩阵乘法。即使np.einsum
用于三维数组,乘积求和通常也只在一对维度上进行(例如“ijk,jl-〉ikl”)3D表示在概念上可能很方便,但我想不出有什么数学运算需要它(而不是2D或1D)。
总的来说,我认为重构数组比尝试寻找/实现真正的3d稀疏运算速度更快。
ssgvzors2#
你说得对看起来并没有现成的工具来处理n维稀疏数组。如果你只需要从数组中访问元素,可以选择使用元组键控的字典。参见:
sparse 3d matrix/array in Python?
如果你需要在稀疏的3d矩阵上做运算,那就变得更难了--你可能要自己做一些编码。
vngu2lb83#
参见python库:https://sparse.pydata.org/en/stable/construct.html
下面是一个2D的例子-从上面提供的页面复制。但是,它也适用于2个以上的维度。我目前正在使用这个库处理可变数量的维度。只是作为一个小注意:在稀疏矩阵具有多于2维的情况下,不可能转换到已知的SciPy稀疏矩阵。
e5nqia274#
看看github/sparse或pytorch-documentation/sparse,参见下面代码片段(pytorchone)。