保存并加载大型numpy矩阵

以下代码是我保存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,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()

那么,对于如此大的数据量,是否有人有更好的解决方案?

hualushui1129 回答:保存并加载大型numpy矩阵

您没有告诉我们您的服务器有多少物理RAM, 但是27 GiB听起来“很多”。 考虑将您的跑步分成几批。

在Java领域中有一个古老的锯问:“为什么它具有二次运行时间?”, 也就是说,“为什么这么慢?”

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()) 然后在循环中分配每个新读取的数组 到其预分配插槽的偏移量中。 线性运行时将使任务更快地完成。

本文链接:https://www.f2er.com/3169603.html

大家都在问