为何numpy.flip()在不改变NumPy数组精度与形状时会减少内存占用
解答:numpy翻转后内存占用显示异常的原因
核心问题是**sys.getsizeof()不适合用来计算numpy数组的实际内存占用**,它的结果不能代表数组数据的真实内存消耗。
具体原因
- 对于原始的numpy数组(连续存储),
sys.getsizeof()返回的是数组对象本身的大小加上其数据缓冲区的大小,所以你看到的1928是对象元数据+30154=1800字节(float32每个元素4字节)的总和,这个值是合理的。 np.flip(img, axis=0)返回的是原数组的视图(非连续数组),此时这个视图对象并不持有自己的数据缓冲区,而是共享原数组的数据。sys.getsizeof()只会计算视图对象本身的元数据大小(比如形状、步长、指针等),也就是你看到的128字节,而不会包含共享的数据内存——这部分内存依然属于原数组,直到原数组被垃圾回收。
验证方法
改用img.nbytes来查看数组数据的实际内存占用:
# 在flip前后分别打印nbytes print("pre-flip nbytes:", img.nbytes) img = np.flip(img, axis=0) print("post-flip nbytes:", img.nbytes)
你会发现两次输出都是30*15*4=1800,说明数据内存根本没有变化,只是sys.getsizeof()的结果误导了你。
补充说明
numpy的视图机制是为了避免不必要的数据复制,提升性能。如果确实需要创建翻转后的副本(独立内存),可以用np.flip(img, axis=0).copy(),此时sys.getsizeof()的结果会回到和原数组相近的值,因为副本持有自己的数据缓冲区。
原问题背景
我写了个把序列数据转稀疏矩阵的函数,发现执行img = np.flip(img, axis=0)后,用sys.getsizeof()查内存占用从1928变成了128。不管怎么加时间窗口长度(稀疏矩阵宽度),翻转后的结果始终是128。我本来以为np.flip()只会创建原矩阵的视图,内存占用不该变,完全搞不懂这情况。
相关函数代码
import sys import numpy as np def gen_img(df, index, interval, height): df = df[index-interval+1: index+1, :5] max_price = df[:, 1].max() min_price = df[:, 2].min() if max_price == min_price: return df, np.zeros((height, interval * 3), dtype="float32") else: df[:, :4] = np.around((height * 4 / 5) * (df[:, :4] - min_price) / (max_price - min_price) + height / 5) df[:, 4] = np.around(df[:, 4].astype("float32") * height / 5 / df[:, 4].max()) df = df.astype(int) img = np.zeros((height, interval * 3), dtype="float32") print("check zero matrix size: {}".format(sys.getsizeof(img))) for i in range(interval): img[df[i, 0], i*3] = 1.0 print("check intermed1 matrix size: {}".format(sys.getsizeof(img))) img[df[i, 3], i*3 + 2] = 1.0 img[df[i, 2] : df[i, 1] + 1, i*3 + 1] = 1.0 img[0 : df[i, 4] + 1, i*3 + 1] = 1.0 print("check intermed2 matrix size: {}".format(sys.getsizeof(img))) img = np.flip(img, axis = 0) print("check generated matrix size: {}".format(sys.getsizeof(img))) return df, img
调试输出
check zero matrix size: 1928, dtype: float32, shape: (30, 15) check intermed1 matrix size: 1928, dtype: float32, shape: (30, 15) check intermed1 matrix size: 1928, dtype: float32, shape: (30, 15) check intermed1 matrix size: 1928, dtype: float32, shape: (30, 15) check intermed1 matrix size: 1928, dtype: float32, shape: (30, 15) check intermed1 matrix size: 1928, dtype: float32, shape: (30, 15) check intermed2 matrix size: 1928, dtype: float32, shape: (30, 15) check generated matrix size: 128, dtype: float32, shape: (30, 15)
内容的提问来源于stack exchange,提问作者royal grasshopper
相关产品推荐
相关产品推荐

