【问题标题】:gzip pickle dump save multiple itemsgzip pickle dump 保存多个项目
【发布时间】:2021-02-12 08:30:04
【问题描述】:

我在使用 gzip 和 pickle 时遇到了一些问题。基本上我有以下代码,我尝试使用 gzip 和 pickle.dump 保存随机数据集

import pickle
import gzip
import torch
import numpy as np

with gzip.open('test.pt', "wb") as f:
    for d in range(50):
        a = np.random.rand(3,2).astype(np.float32)
        aa = torch.from_numpy(a)
        pickle.dump({'name': str(d), 'person': 'test', 'text1':'blah', 
                    'text2': 'blah', 'data': aa}, f)        

with gzip.open('test.pt', "rb") as f:
    data4 = pickle.load(f)
print(data4)

只打印第一个元素,为什么?

我期望上面一行的输出是:

[{'name': '0', 'person': 'test', 'text1': 'blah', 'text2': 'blah',
  'data': tensor([[0.8789, 0.4588],
                  [0.0728, 0.6768],
                  [0.9147, 0.2786]])},
  {'name': '1', 'person': 'test', 'text1': 'blah', 'text2': 'blah',
   'data': tensor([[0.8789, 0.4588],
                   [0.0728, 0.6768],
                   [0.9147, 0.2786]])},
  {'name': '2', 'person': 'test', 'text1': 'blah', 'text2': 'blah',
   'data': tensor([[0.8789, 0.4588],
                   [0.0728, 0.6768],
                   [0.9147, 0.2786]])},
  ...,
  {'name': '49', 'person': 'test', 'text1': 'blah', 'text2': 'blah',
   'data': tensor([[0.8789, 0.4588],
                   [0.0728, 0.6768],
                   [0.9147, 0.2786]])}]
for d in data4:
    print(d)

# prints: name, person, text1, text2, data, why ???**

我的输出除外:

{'name': '0', 'person': 'test', 'text1': 'blah', 'text2': 'blah', 'data': tensor([[0.8789, 0.4588],[0.0728, 0.6768],[0.9147, 0.2786]])}
{'name': '1', 'person': 'test', 'text1': 'blah', 'text2': 'blah', 'data': tensor([[0.8789, 0.4588],[0.0728, 0.6768],[0.9147, 0.2786]])}
{'name': '2', 'person': 'test', 'text1': 'blah', 'text2': 'blah', 'data': tensor([[0.8789, 0.4588],[0.0728, 0.6768],[0.9147, 0.2786]])}
...
{'name': '49', 'person': 'test', 'text1': 'blah', 'text2': 'blah', 'data': tensor([[0.8789, 0.4588],[0.0728, 0.6768],[0.9147, 0.2786]])}

当我这样做时,

for d in data4:
    print(d['name'])

我明白了:

TypeError Traceback (most recent call last)
<ipython-input-25-13370f7fdb11> in <module>
22 
23 for d in data4:
---> 24     print(d['name'])
TypeError: string indices must be integers**

最后真的不明白为什么我无法使用 d['name'] 访问

非常感谢任何帮助!

【问题讨论】:

    标签: python gzip pickle


    【解决方案1】:

    Pickle 是一种独立的格式。您不能简单地连接不同的泡菜对象并让解码器理解结果。如果您想将多个对象写入文件,然后再读取它们,则需要向文件本身添加一些详细信息,以便您知道如何加载各个对象。

    实现此目的的一种简单方法是向文件添加长度以了解每个对象的大小:

    import pickle
    import gzip
    import torch
    import numpy as np
    import struct
    
    with gzip.open('test.pt', "wb") as f:
        for d in range(50):
            a = np.random.rand(3,2).astype(np.float32)
            aa = torch.from_numpy(a)
            temp = pickle.dumps({'name': str(d), 'person': 'test', 'text1':'blah', 
                        'text2': 'blah', 'data': aa})
            f.write(struct.pack("L", len(temp)))
            f.write(temp)
    
    data4 = []
    with gzip.open('test.pt', "rb") as f:
        while True:
            data_length = f.read(4)
            if len(data_length) == 0:
                # No more data
                break
            data_length = struct.unpack("L", data_length)[0]
            data4.append(pickle.loads(f.read(data_length)))
    print(data4)
    

    另外,更直接的是,您可以一次性保存列表:

    data = []
    for d in range(50):
        a = np.random.rand(3,2).astype(np.float32)
        aa = torch.from_numpy(a)
        data.append({'name': str(d), 'person': 'test', 'text1':'blah', 
                    'text2': 'blah', 'data': aa})
    with gzip.open('test.pt', "wb") as f:
        pickle.dump(data, f)
    
    data4 = []
    with gzip.open('test.pt', "rb") as f:
        data4 = pickle.load(f)
    print(data4)
    

    【讨论】:

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