【问题标题】:Use numpy.load on file within zipfile在 zipfile 中的文件上使用 numpy.load
【发布时间】:2016-05-02 13:08:54
【问题描述】:

我有一个 zipfile,其中包含许多 npy 文件(file1.npyfile2.npyfile3.npy、...)。我想单独加载它们而不在文件系统上提取 zipfile。我尝试了很多东西,但我无法弄清楚。

我的猜测是:

import zipfile
import numpy as np

a = {}

with zipfile.ZipFile('myfiles.zip') as zipper:
    for p in zipper.namelist():
        with zipper.read(p) as f:
            a[p] = np.load(f)

有什么想法吗?

【问题讨论】:

  • 你的错误是什么?为什么它不起作用
  • 您可以使用savez_compressed 将它们全部保存到一个*.npz 中,而不是使用多个*.npy 的zip,这样您就不需要手动解压缩它。
  • @kennytm 我无权访问文件的保存方式
  • 我想知道将文件重命名为 *.npz 是否会欺骗 np.load 将其视为 savez 生成的存档。或者直接使用np.lib.npyio.NpzFile
  • @hpaulj 我不明白你的疑惑是我有一个 zipfile 已经包含许多 npy 文件......那么我该如何尝试你的想法?你能写一个完整的答案吗?

标签: python numpy zipfile


【解决方案1】:

保存 2 个数组,每个数组都有自己的文件:

In [452]: np.save('x.npy',x)
In [453]: np.save('y.npy',y)

使用文件浏览器工具,创建zip文件,并尝试加载:

In [454]: np.load('xy.zip')
Out[454]: <numpy.lib.npyio.NpzFile at 0xb48968ec>

看起来np.load 检测到了zip 性质(与名称无关),并返回了一个NpzFile 对象。让我们将它分配给一个变量,然后尝试正常的.npz 提取:

In [455]: xy=np.load('xy.zip')

In [456]: xy['x']
Out[456]: 
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])

In [457]: xy['y']
Out[457]: 
array([[ 0,  4,  8],
       [ 1,  5,  9],
       [ 2,  6, 10],
       [ 3,  7, 11]])

所以load 可以对任何zip 文件或npy 文件执行lazy 加载,无论它是如何创建的。

【讨论】:

  • 非常好的答案!
  • 对于那些感兴趣的人,请阅读npy format。特别是:“对于将多个数组组合成一个文件的简单方法,可以使用 ZipFile 包含多个“.npy”文件。我们建议对这些档案使用文件扩展名“.npz”。”
【解决方案2】:

numpy 函数是否需要一个文件对象,而不是结果文本。对于 zip 文件,我通常会执行以下操作:

with ZipFile(path, mode='r') as archive:
    with io.BufferedReader(archive.open(filename, mode='r')) as file:

我猜你应该将 zipper.open(p, mode='r') 传递给 np.load(f)。另外,我强烈建议您不要执行 zipper.read(p),因为它会立即读取内存中的整个文件。因此,使用您的代码约定,尝试:

with zipfile.ZipFile('myfiles.zip') as zipper:
    for p in zipper.namelist():
        with io.BufferedReader(zipper.open(p, mode='r')) as f:
            a[p] = np.load(f)

【讨论】:

  • zipper.open(p,mode='r') 命令给了我以下错误: Traceback(最近一次调用最后一次):文件“”,第 4 行,在 文件“/usr/local/python/ lib/python2.7/site-packages/numpy/lib/npyio.py", line 379, in load fid.seek(-N, 1) # back-up io.UnsupportedOperation: seek
  • 我编辑了你的答案,所以现在这两个例子都在工作
【解决方案3】:

我将负载替换为 BytesIO。我不知道它是否有效,但可以工作并且更具可读性:)

with ZipFile(fname) as z:
    for p in zipper.namelist():
        tmp =  np.load(io.BytesIO(z.read(p)))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多