【问题标题】:numpy.load retrieves savez'ed arrays in the wrong ordernumpy.load 以错误的顺序检索已保存的数组
【发布时间】:2017-03-21 00:43:27
【问题描述】:

我正在使用存储在列表中的 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 会出现这种奇怪的行为。我是否遗漏了什么,或者我必须使用正则表达式来解决这个问题?

【问题讨论】:

  • data 是一个类似字典的对象,允许通过data['arr_0'] 访问单个数组。字典的键是无序的。
  • @hpaulj:data 类似于字典,data.files 不是。
  • 也许是有意的,savez docs 示例显示了改组的变量名称。目的是数组将按名称而不是按列表顺序返回。

标签: arrays numpy python-3.5


【解决方案1】:

这是由于在numpy中实现了savez。查看source code of 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))]

【讨论】:

  • 所以来自load 的订单与我从unzip -l 得到的订单相同。
  • 文档不保证这一点。 data.files 是通过调用 ZipFile.namelist() 获得的,它没有提及文件名的顺序,这与 ZipFile.infolist() 不同。这很可能是无意的遗漏,但仍然不是您可以依赖的。
  • @pafcu:感谢您的解释,我将使用您的第一个建议对我的列表进行排序。至于您的第二个建议,恐怕它没有抓住重点,因为它只是创建了一个新的有序名称列表,但并不能帮助我整理我的数据文件。无论如何,我不禁想到应该存在一种简单而直接的机制来存储和检索有序的数组列表。我不敢相信我是第一个需要这个的人......
  • 如果您通过将数组作为列表传递来保存数组,那么第二种方法将产生与根据第一种方法排序的data.files 完全相同的列表。它只是一个字符串列表。为什么需要对它们进行排序?
  • 我以为我不应该将list 传递给savez,只有一系列参数,每个参数代表一个数组。这就是为什么我想以相同的顺序检索它们,因为这是我将检索到的数据放在正确位置的唯一方法。与我上面问题中的示例不同,我的实际数组的形状都不同。因此,将list 传递给savez 将生成一个多数组,尽管如果我的数组碰巧都具有相同的形状,它将生成一个多维的普通numpy.ndarray。根据内容不同的文件格式,我不喜欢这样。
猜你喜欢
  • 2011-06-24
  • 2022-10-01
  • 1970-01-01
  • 2020-09-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多