保存和加载大型 numpy 矩阵

saving and loading large numpy matrix

下面的代码是我保存numpy数组的方法,保存后大约有27GB。图片数据超过200K,每个形状为(224,224,3)

hf = h5py.File('cropped data/features_train.h5', 'w')
for i,each in enumerate(features_train):
    hf.create_dataset(str(i), data=each)
hf.close()

这是我用来加载数据的方法,加载需要几个小时。

features_train = np.zeros(shape=(1,224,224,3))    
hf =  h5py.File('cropped data/features_train.h5', 'r') 
for key in hf.keys():
    x = hf.get(key)
    x = np.array(x)
    features_train = np.append(features_train,np.array([x]),axis=0) 
hf.close()

那么,对于这么大的数据量,有没有人有更好的解决方案呢?

您没有告诉我们您的服务器有多少物理 RAM, 但是 27 GiB 听起来像 "a lot"。 考虑将您的 运行 分成几个较小的批次。

java 土地上有一把老锯问 "why does this have quadratic runtime?", 也就是说,"why is this so slow?"

String s = ""
for (int i = 0; i < 1e6, i++) {
    s += "x";
}

答案是,到最后, 在我们正在阅读的每次迭代中~一百万个字符 然后写它们,然后附加一个字符。 成本是 O(1e12)。 标准解决方案是使用 StringBuilder 所以我们回来了 到预期的 O(1e6).

在这里,我担心调用 np.append() 会将我们推入二次状态。

要验证,请将 features_train 赋值替换为简单的评估 np.array([x]),所以我们花点时间计算然后立即丢弃 每次迭代的那个值。 如果猜想正确,运行时间会小很多

要补救,请避免调用 .append()。 相反,使用 np.zeros() 预分配 27 GiB (或 np.empty()) 然后在循环内分配每个新读取的数组 进入其预分配插槽的偏移量。 线性 运行 时间将使任务完成得更快。