处理大尺寸NumPy视图时np.reshape失效,如何无内存过载重设形状?
问题描述
我有一个尺寸为(512,512,100)的np.float64类型初始NumPy数组,使用view_as_windows函数得到尺寸为(499,499,100,64,64)的视图(该视图内存占用远小于实际数组)。我想将其重设形状为(499*499*100,64,64),但常规np.reshape耗时久且因转成实际数组而崩溃,尝试了以下代码均无效:
# gs.shape gives (499,499,100,64,64) gs.shape = (gs.shape[0]*gs.shape[1]*gs.shape[2],64,64,) gs = np.reshape(gs,(gs.shape[0]*gs.shape[1]*gs.shape[2],64,64,)) gs = gs.reshape(gs.shape[0]*gs.shape[1]*gs.shape[2],64,64,)
请问如何在不造成内存过载的情况下修改该视图的形状?
解决方案
首先明确:view_as_windows生成的视图内存布局不连续,无法直接通过无复制的方式合并前三个维度——因为这三个维度对应的内存地址不是连续递增的,强行合并必须复制数据,这也是你用常规reshape崩溃的原因。
给你两个可行方向:
1. 分批次处理(推荐,避免内存过载)
不需要一次性合并全部数据,按维度切片处理,每次只加载小批量数据到内存:
# 按第三个维度(100个切片)分批处理 for k in range(gs.shape[2]): # 取出当前k对应的所有窗口,合并成(N,64,64),N=499*499 batch = gs[:, :, k, :, :].reshape(-1, 64, 64) # 在这里处理batch,比如做计算、保存等 # process_batch(batch) # 如果单批次还是太大,可再拆分第一个维度 for i in range(gs.shape[0]): for k in range(gs.shape[2]): batch = gs[i, :, k, :, :].reshape(-1, 64, 64) # process_batch(batch)
2. 强制复制(仅当内存足够时使用)
复制后数组体积约为800GB(499*499*100*64*64*8字节),远超常规内存容量,仅当你有足够内存时可尝试:
gs_reshaped = gs.reshape(-1, 64, 64, order='A')
为什么你的代码无效?
你尝试的直接修改shape或调用reshape,在数组内存不连续时都会触发数据复制,而目标数组体积过大,直接导致内存溢出崩溃。
内容的提问来源于stack exchange,提问作者rando
相关产品推荐
相关产品推荐

