如何计算scipy.sparse.lil_matrix的字节大小?
测量scipy.sparse.lil_matrix的内存占用问题
为什么常规方法失效?
sys.getsizeof():仅返回对象自身的内存大小,不包含其内部引用的子对象(比如data/rows里的嵌套列表、元素),无法反映添加元素后的变化。sparse_lil.data.nbytes:该方法仅适用于numpy数组,但lil_matrix的data是Python列表的列表,不是numpy数组,因此调用无意义,返回值固定。- pympler的
asizeof:默认递归逻辑未正确遍历lil_matrix的内部嵌套结构,导致结果不准确。
正确的测量方法
lil_matrix的核心存储是data(每行非零值的列表)和rows(每行非零列索引的列表),均为嵌套Python列表。要计算总内存占用,需递归遍历这些嵌套结构,累加所有对象的大小。
方法1:计算完整内存占用(含所有Python对象开销)
import sys import numpy as np from scipy.sparse import lil_matrix def calculate_lil_total_size(lil_mat): total = sys.getsizeof(lil_mat) # 矩阵对象本身的内存 # 遍历data中的所有子列表及元素 for row_data in lil_mat.data: total += sys.getsizeof(row_data) for elem in row_data: total += sys.getsizeof(elem) # 遍历rows中的所有子列表及元素 for row_indices in lil_mat.rows: total += sys.getsizeof(row_indices) for idx in row_indices: total += sys.getsizeof(idx) # 加上其他属性的内存(如dtype、shape) total += sys.getsizeof(lil_mat.dtype) total += sys.getsizeof(lil_mat.shape) return total # 测试 mat = lil_matrix((4,4), dtype=np.int32) print(f"初始大小: {calculate_lil_total_size(mat)} 字节") mat[0,0] = 1 print(f"添加1个元素后大小: {calculate_lil_total_size(mat)} 字节") mat[1,2] = 5 print(f"添加2个元素后大小: {calculate_lil_total_size(mat)} 字节")
方法2:计算原始数据+列表结构开销(不含Python标量对象开销)
如果仅关心实际存储的数值数据,加上列表的结构开销,可使用此方法:
def calculate_lil_raw_size(lil_mat): # 原始数值数据的字节数(非零元素数 × 单个元素字节数) raw_data_size = lil_mat.nnz * lil_mat.dtype.itemsize # 列表结构的开销 struct_size = 0 for row in lil_mat.data: struct_size += sys.getsizeof(row) for row in lil_mat.rows: struct_size += sys.getsizeof(row) return raw_data_size + struct_size
说明
- 方法1的结果包含所有Python对象的内存开销(比如每个int32数值作为Python对象的额外开销),更贴近实际内存占用。
- 方法2仅计算原始数据和列表结构的大小,适合关注数据本身的存储成本。
内容的提问来源于stack exchange,提问作者scideas
相关产品推荐
相关产品推荐

