未知数组尺寸时如何定义空numpy数组并实现动态扩展
Numpy动态扩展数组解决方案
基础实现思路
Numpy数组本质是固定大小的连续内存块,动态扩展的底层逻辑是重新分配内存、拷贝原有数据到新内存地址,不需要借助列表即可实现,以下是两种常见场景的实现方案:
场景1:每次新增内容与原有数组维度对齐
如果每次新增的内容,除了拼接维度外的其他维度和已有数组完全一致,可以使用numpy.append或者numpy.concatenate实现扩展:
import numpy as np # 初始化空数组,提前确定非拼接维度的形状,比如后续要沿0维拼接,每个元素是长度为3的一维数组 arr = np.empty((0, 3), dtype=np.float64) for i in range(10): # 模拟生成符合形状要求的新元素 new_val = np.random.rand(3) # 扩展数组,新增维度保证和原数组维度匹配 arr = np.append(arr, new_val[np.newaxis, :], axis=0)
你也可以使用np.resize直接修改数组形状,提前分配足够空间后用切片赋值,比多次append性能更好:
import numpy as np # 预估最大长度为100,初始可以设小,后续按需扩容 arr = np.empty((0, 3), dtype=np.float64) current_len = 0 for i in range(50): new_val = np.random.rand(3) current_len += 1 # 空间不够时扩容为原来的2倍,减少拷贝次数 if current_len > arr.shape[0]: arr = np.resize(arr, (max(arr.shape[0]*2, 1), 3)) arr[current_len-1] = new_val # 最后截断到实际使用的长度 arr = arr[:current_len]
场景2:每次新增内容形状完全不同
如果每次生成的数组形状没有统一规则,比如第一次生成(2,2)的二维数组,第二次生成(3,)的一维数组,可以使用dtype为object的Numpy数组存储不同形状的子数组:
import numpy as np # 初始化空对象数组 arr = np.array([], dtype=object) for i in range(10): # 模拟生成随机形状的数组 random_dim = np.random.randint(1,4) random_shape = tuple(np.random.randint(1,5) for _ in range(random_dim)) new_val = np.random.rand(*random_shape) # 直接追加元素 arr = np.append(arr, new_val)
注意:动态扩展会带来额外的内存拷贝开销,数据量较大的场景下如果可以预估最大容量,优先选择预分配足够大小的数组、后续用切片赋值的方案,性能会有明显提升
内容的提问来源于stack exchange,提问作者Kadaj13
相关产品推荐
相关产品推荐

