我使用的是存储在列表中的numpy数组。这些数组没有单独的名称,我只是通过它们在列表中的索引来调用它们。
我需要一起保存和检索它们,因此我使用numpy.savez
将它们存储到单个文件中。由于我的数组是未命名的,我只是枚举了列表,numpy.savez
为它们自动分配了名称"arr_0"、"arr_1",等等。
但是当我试图使用numpy.load
检索它们时,我发现numpy.load
以看似随机的顺序列出数组。当然,我可以在恢复数组之前对这个列表进行排序,但是我发现非常奇怪的是,没有直接的方法来存储和检索未命名数组的有序列表。
import numpy as np
arr_list = []
for i in range(15):
arr_list.append(np.array(range(i, i+6)).reshape(2, 3))
np.savez('testfile', *arr_list)
with np.load('testfile.npz') as data:
print(data.files)
我得到的结果是:
>>> ['arr_1', 'arr_3', 'arr_13', 'arr_11', 'arr_14', 'arr_10', 'arr_8', 'arr_0',
'arr_2', 'arr_9', 'arr_5', 'arr_4', 'arr_6', 'arr_12', 'arr_7']
更重要的是,我从来没有得到两次相同的结果。下一个尝试:
>>> ['arr_6', 'arr_11', 'arr_10', 'arr_13', 'arr_0', 'arr_7', 'arr_5', 'arr_3',
'arr_14', 'arr_2', 'arr_8', 'arr_12', 'arr_1', 'arr_9', 'arr_4']
不幸的是,我不能使用sorted()
对列表进行排序,因为结果不是我需要的(这就是为什么我在列表中给出了一个超过10项的示例):
>>> ['arr_0', 'arr_1', 'arr_10', 'arr_11', 'arr_12', 'arr_13', 'arr_14', 'arr_2',
'arr_3', 'arr_4', 'arr_5', 'arr_6', 'arr_7', 'arr_8', 'arr_9']
我不明白为什么numpy.savez
+ numpy.load
会有这样奇怪的行为。是我错过了什么,还是我必须使用正则表达式来解决这个问题?
这是由于在numpy中实现了savez
。查看savez的源代码,我们看到要保存的数组列表(包含在args
参数中)被添加到包含要存储的数组(kwargs
参数)的字典中。args
列表中数组的顺序在此阶段可能会丢失(取决于所使用的Python版本)。
既然你知道文件名的格式,你可以对它们进行排序
sorted_files = sorted(data.files, key=lambda x:int(x[4:]))
或重新创建列表
sorted_files = ['arr_{}'.format(i) for i in range(len(data.files))]