使用Pickle保存Numpy数组

Ana*_*ant 7 python numpy pickle

我有一个Numpy数组,我想保存(130,000 x 3)我想使用Pickle保存,使用以下代码.但是,我一直在pkl.load行中收到错误"EOFError:Ran out of input"或"UnsupportedOperation:read".这是我第一次使用Pickle,任何想法?

谢谢,

一只蚂蚁

import pickle as pkl
import numpy as np

arrayInput = np.zeros((1000,2)) #Trial input
save = True
load = True

filename = path + 'CNN_Input'
fileObject = open(fileName, 'wb')

if save:
    pkl.dump(arrayInput, fileObject)
    fileObject.close()

if load:
    fileObject2 = open(fileName, 'wb')
    modelInput = pkl.load(fileObject2)
    fileObject2.close()

if arrayInput == modelInput:
    Print(True)
Run Code Online (Sandbox Code Playgroud)

pio*_*kuc 20

你应该使用numpy.savenumpy.load.

  • 点赞。`pickle` 适用于任意 Python 数据。`np.save` 和 `np.load` 对数字数据将更加*高效。 (3认同)
  • 我现在无法测试它,但我认为“保存”是一种麻木的酸洗方法。相反,`save` 使用pickle 来写入非数组元素。 (3认同)
  • 也许对“np.save”与“np.savez”的评论会有所帮助。 (3认同)
  • 你能评论一下使用pickle有什么问题吗?提前致谢。 (2认同)

Cha*_*ker 8

不要将 pickle 用于 numpy 数组,有关链接到我能找到的所有资源的扩展讨论,请参阅我的答案here

简短理由:

  • numpy 的开发人员已经制作了一个很好的界面,将为您节省大量调试时间(最重要的原因
  • np.save,np.load,np.savez在大多数指标中都有相当好的性能,请参阅this,这是可以预料的,因为它是一个成熟的库,并且 numpy 的开发人员制作了这些函数。
  • Pickle 执行任意代码,是一个安全问题
  • 要使用pickle,您必须打开并归档,并且可能会遇到导致错误的问题(例如,我不知道使用b它,它停止工作,需要时间来调试)
  • 如果你拒绝接受这个建议,至少要明确说明你需要使用其他东西的原因。确保它在你的头脑中清晰可见。

如果解决方案已经存在,请不惜一切代价避免重复代码!

无论如何,这是我尝试过的所有界面,希望它可以节省某人的时间(可能是我未来的自己):

import numpy as np
import pickle
from pathlib import Path

path = Path('~/data/tmp/').expanduser()
path.mkdir(parents=True, exist_ok=True)

lb,ub = -1,1
num_samples = 5
x = np.random.uniform(low=lb,high=ub,size=(1,num_samples))
y = x**2 + x + 2

# using save (to npy), savez (to npz)
np.save(path/'x', x)
np.save(path/'y', y)
np.savez(path/'db', x=x, y=y)
with open(path/'db.pkl', 'wb') as db_file:
    pickle.dump(obj={'x':x, 'y':y}, file=db_file)

## using loading npy, npz files
x_loaded = np.load(path/'x.npy')
y_load = np.load(path/'y.npy')
db = np.load(path/'db.npz')
with open(path/'db.pkl', 'rb') as db_file:
    db_pkl = pickle.load(db_file)

print(x is x_loaded)
print(x == x_loaded)
print(x == db['x'])
print(x == db_pkl['x'])
print('done')
Run Code Online (Sandbox Code Playgroud)

但最有用的请参阅我的答案


hpa*_*ulj 7

我使用没有问题pickle

In [126]: arr = np.zeros((1000,2))
In [127]: with open('test.pkl','wb') as f:
     ...:     pickle.dump(arr, f)
     ...:     
In [128]: with open('test.pkl','rb') as f:
     ...:     x = pickle.load(f)
     ...:     print(x.shape)
     ...:     
     ...:     
(1000, 2)
Run Code Online (Sandbox Code Playgroud)

pickle并且np.save/load有很深的互惠。就像我可以用以下方法加载此泡菜np.load

In [129]: np.load('test.pkl').shape
Out[129]: (1000, 2)
Run Code Online (Sandbox Code Playgroud)

如果我以错误的方式打开pickle文件,我会得到您的错误:

In [130]: with open('test.pkl','wb') as f:
     ...:     x = pickle.load(f)
     ...:     print(x.shape)
     ...:    
UnsupportedOperation: read
Run Code Online (Sandbox Code Playgroud)

但这并不奇怪-您不能读取新打开的写入文件。它是空的。

np.save/load是用于编写numpy数组的常用对。但是pickle用于save序列化数组,并save使用pickle序列化非数组对象(在数组中)。结果文件大小相似。奇怪的是,泡菜版本的速度更快。


小智 6

这已经有点过了,但如果你发现了这个,Pickle 会在很短的时间内完成。

with open('filename','wb') as f: pickle.dump(arrayname, f)

with open('filename','rb') as f: arrayname1 = pickle.load(f)

numpy.array_equal(arrayname,arrayname1) #sanity check
Run Code Online (Sandbox Code Playgroud)

另一方面,默认情况下 numpy 压缩将我的 5.2GB 降到 .4GB,而 Pickle 降到 1.7GB。