python-3.x - 保存和加载大型 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,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 听起来“很多”。考虑将您的运行分成几个较小的批次。
在 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()
相反,使用(or )预分配 27 GiB,np.empty()
然后在循环内将每个新读取的数组分配到其预分配槽的偏移量中。线性运行时将允许任务更快地完成。
推荐阅读
- python - 从分层DataFrame中按最大值选择行
- kotlin - 在 Kotlin/JVM 中加载 Kotlin/Native 共享库
- php - Apache / Laravel 不缓存 jpg,但缓存了其他扩展
- vue.js - 修改从 Vuex Store 获取的变量
- python - Keras Conv1d 输入形状:检查输入时出错
- scala - 如何在 Akka Actor 中检查消息是否有发件人
- javascript - 如何使网页中的表格垂直滚动,同时使其他所有内容固定到位
- python - 如何交替打印 2 个变量 n 次
- postgresql - 为什么运行查询在消息下返回“table_oid”而在数据输出下没有任何内容
- json - React Native:如何访问 JSON 对象中的数据?