切片后追加恢复原形状是否增内存?循环脚本是否存内存泄漏?
NumPy视图与np.append的内存占用及内存泄漏问题
先看这段代码:
x = np.random.rand(3, 4) x = x[1:] x = np.append(x, np.random.rand(1, 4), axis=0)
第二行代码创建的是原始数组的视图,不会额外占用内存。我有两个疑问:
- 第三行的
np.append是否会增加内存占用?- 假设1:如果
append无视视图,直接复制原始数据再追加新内容,内存占用会上升 - 假设2:如果
append基于视图构造更小的数组再追加,内存占用不会增加
- 假设1:如果
- 下面的循环脚本是否存在内存泄漏?
x = np.random.rand(3, 4) for _ in range(1000000): x = x[1:] x = np.append(x, np.random.rand(1, 4), axis=0)
解答
np.append会产生临时内存占用
NumPy数组的内存是连续存储的,np.append的工作机制是:不管输入是原数组还是视图,都会创建一块新的连续内存区域,把输入数组的所有数据复制进去,再追加新的元素。执行完第三行后,原数组如果没有其他引用,会被Python的垃圾回收机制清理,但append执行过程中确实会因为复制数据产生额外的内存占用,执行后旧内存会被释放。循环脚本不会出现内存泄漏
每次循环中:
x = x[1:]创建视图,不占用新内存np.append创建新数组,此时旧的x(包括之前的原数组或视图对应的数组)因为没有其他引用,会被垃圾回收
循环过程中,内存只会保留当前的3行数组,以及append执行时的临时内存,整体内存占用会维持稳定,不会持续增长,因此不存在内存泄漏。
不过这种写法效率极低,百万次循环会因为频繁复制数据导致运行极慢。更优的做法是预先分配足够内存,或者用列表暂存每行数据,最后再转换为NumPy数组。
内容的提问来源于stack exchange,提问作者Jeffrey Chen
相关产品推荐
相关产品推荐

