使用scipy稀疏矩阵构建三维空间模型触发内存错误如何解决
问题原因
首先纠正你的认知误区:空CSR稀疏矩阵并不是几乎不占内存,CSR格式的存储结构决定了它必须初始化固定长度的元数据数组,和矩阵是否为空无关:
- CSR矩阵核心由三个数组构成:
indptr(行指针数组,长度=行数+1)、indices(列索引数组,长度=非零元素个数)、data(数值数组,长度=非零元素个数) - 你创建的每个CSR矩阵行数
stepX = 10*1e6 = 10^7,所以哪怕是空矩阵,也必须初始化长度为10^7 +1的indptr数组,类型为int32时占用的内存正好是报错里的38.1MiB - 你代码里计划创建的矩阵总数是
stepZ=100*1e6=1e7个,仅3100个矩阵的indptr数组就已经占用了3100*38MiB ≈ 115GiB,远超过你的32GB内存上限,触发内存错误是必然结果。
另外还有两个额外的错误设计:
- 你用自定义
particle类作为矩阵dtype,numpy会将其识别为对象类型,相比原生数值类型内存开销高几倍,还会大幅降低运算效率 - 你的三维空间建模思路完全错误:1e19的点位根本不可能用预分配矩阵的方式实现,不管是稠密还是稀疏矩阵都不可能,预分配空矩阵的行为本身就是浪费内存。
解决方案
完全抛弃当前预创建二维稀疏矩阵列表的架构,改用坐标存储方案:
- 仅存储存在粒子的点位坐标和属性:可以用字典,键为
(x,y,z)整数元组,值为对应的particle对象,只有实际存在粒子的位置才会占用内存,内存占用仅和粒子总量挂钩,和总空间大小无关 - 如果需要做批量数值运算,可以把所有有粒子的坐标单独存为三个1D数组
x_arr、y_arr、z_arr,粒子属性对应存为同长度的数组,运算时直接操作这几个数组即可,效率远高于稀疏矩阵方案 - 如果确实需要用稀疏结构存储三维数据,可以选择
scipy.sparse中的coo_matrix存储全局展平的坐标,或者使用专门的三维稀疏数组库,但依然不要预分配空结构,仅在有粒子的位置赋值。
内容的提问来源于stack exchange,提问作者EXIT_FAILURE
相关产品推荐
相关产品推荐

