- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
这里是第一个问题。我会尽量简洁。
我正在为机器学习应用程序生成包含特征信息的多个数组。由于数组的维度不同,我将它们存储在字典中而不是数组中。有两种不同的功能,所以我使用了两种不同的词典。
我还生成标签以配合这些功能。这些标签存储在数组中。此外,还有一些字符串包含用于运行脚本的确切参数和时间戳。
总而言之,它看起来像这样:
import numpy as np
feature1 = {}
feature2 = {}
label1 = np.array([])
label2 = np.array([])
docString = 'Commands passed to the script were...'
# features look like this:
feature1 = {'case 1': np.array([1, 2, 3, ...]),
'case 2': np.array([2, 1, 3, ...]),
'case 3': np.array([2, 3, 1, ...]),
and so on... }
现在我的目标是这样做:
np.savez(outputFile,
saveFeature1 = feature1,
saveFeature2 = feature2,
saveLabel1 = label1,
saveLabel2 = label2,
saveString = docString)
这似乎有效(即这样的文件保存时没有抛出错误并且可以再次加载)。但是,当我尝试再次从文件加载功能时:
loadedArchive = np.load(outFile)
loadedFeature1 = loadedArchive['saveFeature1']
loadedString = loadedArchive['saveString']
然后我没有取回字典,而是得到一个形状为 (0) 的 numpy 数组,我不知道如何访问其中的内容:
In []: loadedFeature1
Out[]:
array({'case 1': array([1, 2, 3, ...]),
'case 2': array([2, 3, 1, ...]),
..., }, dtype=object)
字符串也变成数组并得到一个奇怪的数据类型:
In []: loadedString.dtype
Out[]: dtype('|S20')
简而言之,我假设这不是正确的做法。但是,我不希望将所有变量都放入一个大字典中,因为我将在另一个进程中检索它们,并且只想循环遍历 dictionary.keys() 而不必担心字符串比较。
非常感谢任何想法。谢谢
最佳答案
正如@fraxel 已经建议的那样,在这种情况下使用 pickle 是一个更好的选择。只需保存一个包含您的项目的 dict
。
但是,请务必将 pickle 与二进制协议(protocol)一起使用。默认情况下,它的格式化效率较低,如果您的数组很大,这将导致过多的内存使用和巨大的文件。
saved_data = dict(outputFile,
saveFeature1 = feature1,
saveFeature2 = feature2,
saveLabel1 = label1,
saveLabel2 = label2,
saveString = docString)
with open('test.dat', 'wb') as outfile:
pickle.dump(saved_data, outfile, protocol=pickle.HIGHEST_PROTOCOL)
话虽如此,为了便于说明,让我们更详细地看一下发生了什么。
numpy.savez
期望每个项目都是一个数组。事实上,它会在您传入的所有内容上调用 np.asarray
。
如果将 dict
转换为数组,您将得到一个对象数组。例如
import numpy as np
test = {'a':np.arange(10), 'b':np.arange(20)}
testarr = np.asarray(test)
类似地,如果你用字符串创建一个数组,你会得到一个字符串数组:
In [1]: np.asarray('abc')
Out[1]:
array('abc',
dtype='|S3')
但是,由于处理对象数组的方式有一个怪癖,如果您传入一个不是元组、列表或数组的对象(在您的情况下,您的 dict
) ,你会得到一个 0 维对象数组。
这意味着你不能直接索引它。事实上,执行 testarr[0]
会引发 IndexError
。数据还在,但你需要先添加一个维度,所以你必须做yourdictionary = testarr.reshape(-1)[0]
。
如果所有这些看起来都很笨拙,那是因为它确实很笨重。对象数组基本上总是错误的答案。 (虽然 asarray
应该将 ndmin=1
传递给 array
,这可以解决这个特定问题,但可能会破坏其他东西。)
savez
旨在存储数组,而不是任意对象。由于它的工作方式,它可以完全存储任意对象,但不应该那样使用它。
不过,如果您确实想使用它,一个快速的解决方法是:
np.savez(outputFile,
saveFeature1 = [feature1],
saveFeature2 = [feature2],
saveLabel1 = [label1],
saveLabel2 = [label2],
saveString = docString)
然后您可以使用
访问内容loadedArchive = np.load(outFile)
loadedFeature1 = loadedArchive['saveFeature1'][0]
loadedString = str(loadedArchive['saveString'])
但是,这显然比只使用 pickle 笨拙得多。仅在保存数组时使用 numpy.savez
。在这种情况下,您保存的是嵌套数据结构,而不是数组。
关于python - 如何将字典和数组保存在同一个存档中(使用 numpy.savez),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10075661/
我是一名优秀的程序员,十分优秀!