Numpy savez 将我的键解释为文件名 -> IOError

3 投票
2 回答
1298 浏览
提问于 2025-04-17 12:56

我正在使用 numpy的savez 方法,正如推荐的那样来保存numpy数组。作为键,我使用的是我加载数据时的文件名。但是看起来 savez 好像在某种程度上试图使用这些文件名。我该怎么办呢?我希望能避免去掉文件名中的路径和后缀。

>>> import numpy
>>> arrs = {'data/a.text': numpy.array([1,2]),
            'data/b.text': numpy.array([3,4]),
            'data/c.text': numpy.array([5,6])}    
>>> numpy.savez('file.npz', **arrs)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "/usr/lib/python2.6/dist-packages/numpy/lib/io.py", line 305, in savez
    fid = open(filename,'wb')
IOError: [Errno 2] No such file or directory: '/tmp/data/c.text.npy'

2 个回答

1

可能是因为 savez 在创建临时文件时,使用了字典中给定的名字。这个文件名里面有一个 / 符号。当 savez 创建文件时,它试图用这个名字和扩展名 .npy(比如 data/c.txt.py)在临时目录中创建文件。但是,这个新路径指向了一个不存在的子目录 temp,所以就出现了错误。

解决办法是:要么把斜杠换成其他符号,要么可以尝试对文件名进行转义处理。

(我之前的回答太复杂了,可能也不太对。)

2

在把密钥传递给 savez 函数之前,你可以先对它进行编码和解码。

>>> import numpy
>>> import base64
>>> arrs = {'data/a.text': numpy.array([1,2]),
            'data/b.text': numpy.array([3,4]),
            'data/c.text': numpy.array([5,6])}
>>> numpy.savez('file.npz', **dict((base64.urlsafe_b64encode(k), v)
                                    for k,v in arrs.iteritems()))
>>> npzfile = numpy.load('file.npz')
>>> decoded = dict((base64.urlsafe_b64decode(k), v)
                   for k,v in npzfile.iteritems())
>>> decoded
{'data/c.text': array([5, 6]),
 'data/a.text': array([1, 2]),
 'data/b.text': array([3, 4])}

撰写回答