如何在循环中迭代将子numpy数组添加到父numpy数组
解决方案:在循环中合并多个(10,3) NumPy数组为(X,10,3)数组
最优方案:用Python列表收集后转NumPy数组
你目前采用的方法其实是NumPy官方推荐的高效实现——NumPy数组的内存是连续固定的,每次循环中直接拼接数组会频繁触发内存重新分配与数据拷贝,效率极低。而Python列表的动态扩容开销更小,最后一次性转换为数组的性能更优。示例代码:
import numpy as np list_of_arr = [] # 模拟循环生成子数组 for _ in range(3): # 生成(10,3)的示例数组 sub_arr = np.random.rand(10, 3).astype(np.float32) list_of_arr.append(sub_arr) # 转换为目标维度(X,10,3)的数组 parent_arr = np.array(list_of_arr) print(parent_arr.shape) # 输出(3,10,3)
原生NumPy循环拼接的方法(不推荐,效率偏低)
如果一定要在循环中用NumPy原生函数实现,有两种方式,但性能均不如列表收集方案:
1. 预先分配数组并填充
若提前知晓子数组的数量X,可以先创建空的目标数组,再在循环中逐个填充:
X = 3 # 预先分配内存 parent_arr = np.empty((X, 10, 3), dtype=np.float32) for i in range(X): sub_arr = np.random.rand(10, 3).astype(np.float32) parent_arr[i] = sub_arr
2. 循环中使用np.concatenate(需扩展子数组维度)
每次循环时,先将(10,3)的子数组扩展为(1,10,3),再与已有的父数组在axis=0维度拼接:
# 初始化父数组为第一个子数组扩展维度后的结果 parent_arr = np.expand_dims(np.random.rand(10,3).astype(np.float32), axis=0) for _ in range(2): # 再添加2个子数组 sub_arr = np.random.rand(10,3).astype(np.float32) # 扩展维度后拼接 parent_arr = np.concatenate([parent_arr, np.expand_dims(sub_arr, axis=0)], axis=0) print(parent_arr.shape) # 输出(3,10,3)
注意:这种方法每次循环都会创建新数组并拷贝数据,当X较大时性能会明显下降,不建议使用。
为什么之前stack/concatenate未达到预期?
np.stack默认会在新维度堆叠数组,若循环中每次仅传入现有父数组+新子数组,会导致维度不断嵌套(比如第一次堆叠后是(2,10,3),第二次直接堆叠会变成(2,2,10,3)),它的作用是对多个数组的新维度批量堆叠,而非追加元素。np.concatenate要求拼接的数组维度一致,因此必须先将(10,3)的子数组扩展为(1,10,3),才能与已有的(X,10,3)数组在axis=0维度拼接。
内容的提问来源于stack exchange,提问作者ricardlambea
相关产品推荐
相关产品推荐

