Python 使用Pickle保存Numpy数组

Python 使用Pickle保存Numpy数组,python,numpy,pickle,Python,Numpy,Pickle,我有一个Numpy数组,我想保存它(130000 x 3),我想用Pickle保存它,代码如下。但是,我在pkl.load行中不断收到错误“EOFError:run-out-of-input”或“unsupportdoOperation:read”。这是我第一次用泡菜,有什么想法吗 谢谢 阿南特 您应该使用和。我使用pickle时没有问题: In [126]: arr = np.zeros((1000,2)) In [127]: with open('test.pkl','wb') as f:

我有一个Numpy数组,我想保存它(130000 x 3),我想用Pickle保存它,代码如下。但是,我在pkl.load行中不断收到错误“EOFError:run-out-of-input”或“unsupportdoOperation:read”。这是我第一次用泡菜,有什么想法吗

谢谢

阿南特


您应该使用和。

我使用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)
pickle
np.save/load
有着深刻的相互作用。就像我可以用
np加载这个pickle一样。加载

In [129]: np.load('test.pkl').shape
Out[129]: (1000, 2)
如果我以错误的方式打开pickle文件,我确实会收到您的错误:

In [130]: with open('test.pkl','wb') as f:
     ...:     x = pickle.load(f)
     ...:     print(x.shape)
     ...:    
UnsupportedOperation: read
但这并不奇怪——您无法读取新打开的写入文件。它将是空的


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

虽然有点慢,但如果你发现了这一点,pickle只需很短的时间就可以完成

打开('filename','wb')作为f:pickle.dump(arrayname,f)
将open('filename','rb')作为f:arrayname1=pickle.load(f)
numpy.array_equal(arrayname,arrayname1)#健全性检查

另一方面,默认情况下,numpy compress将我的5.2GB降至.4GB,Pickle降至1.7GB。

您应该使用
numpy.save()
保存numpy矩阵

在代码中,您正在使用

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

open
函数中的第二个参数是方法
w
代表书写,
r
代表阅读。第二个字符
b
表示将读取/写入字节。将写入的文件无法读取,反之亦然。因此,使用
fileObject2=open(fileName,'rb')
打开文件就可以了。

不要对numpy数组使用pickle,这是一个链接到我能找到的所有资源的扩展讨论

简短理由:

  • numpy的开发者已经制作了一个很好的界面,可以为您节省大量的调试时间(最重要的原因
  • np.save、np.load、np.savez
    在大多数度量中都有相当好的性能,请参阅,这是意料之中的,因为它是一个已建立的库,并且是numpy的开发人员开发的这些函数
  • Pickle执行任意代码,这是一个安全问题
  • 要使用pickle,您必须打开并归档,可能会遇到导致bug的问题(例如,我不知道使用
    b
    ,并且它停止工作,需要时间进行调试)
  • 如果你拒绝接受这个建议,至少要清楚地说明你需要使用其他东西的原因。确保你的头脑里清楚无误
如果已经存在解决方案,请避免不惜一切代价重复代码

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


但最有用的是查看我的答案。

保存和加载NumPy数组的最简单方法-

# a numpy array

result.importances_mean
array([-1.43651529e-03, -2.73401297e-03,  9.26784059e-05, -7.41427247e-04,
        3.56811863e-03,  2.78035218e-03,  3.70713624e-03,  5.51436515e-03,
        1.16821131e-01,  9.26784059e-05,  9.26784059e-04, -1.80722892e-03,
       -1.71455051e-03, -1.29749768e-03, -9.26784059e-05, -1.43651529e-03,
        0.00000000e+00, -1.11214087e-03, -4.63392030e-05, -4.63392030e-04,
        1.20481928e-03,  5.42168675e-03, -5.56070436e-04,  8.34105653e-04,
       -1.85356812e-04,  0.00000000e+00, -9.73123262e-04, -1.43651529e-03,
       -1.76088971e-03])

# save the array format - np.save(filename.npy, array)

np.save(os.path.join(model_path, "permutation_imp.npy"), result.importances_mean)

# load the array format - np.load(filename.npy)

res = np.load(os.path.join(model_path, "permutation_imp.npy"))
res
array([-1.43651529e-03, -2.73401297e-03,  9.26784059e-05, -7.41427247e-04,
        3.56811863e-03,  2.78035218e-03,  3.70713624e-03,  5.51436515e-03,
        1.16821131e-01,  9.26784059e-05,  9.26784059e-04, -1.80722892e-03,
       -1.71455051e-03, -1.29749768e-03, -9.26784059e-05, -1.43651529e-03,
        0.00000000e+00, -1.11214087e-03, -4.63392030e-05, -4.63392030e-04,
        1.20481928e-03,  5.42168675e-03, -5.56070436e-04,  8.34105653e-04,
       -1.85356812e-04,  0.00000000e+00, -9.73123262e-04, -1.43651529e-03,
       -1.76088971e-03])

FileObject2应该打开读,而不是写。我很困惑,
pickle与np.save/z
等的优缺点是什么?这里的解决方案对您有帮助吗?如果不是的话,你介意澄清一下他们的问题吗?向上投票<代码>pickle
适用于任意python数据
np.save
np.load
对于数值数据来说效率更高。我现在无法测试它,但我认为
save
是numpy酸洗方法。相反地,
save
使用pickle编写非数组元素。如建议的,请查看完整的示例代码。您能评论一下使用pickle的错误吗?提前谢谢。也许对
np.save
vs
np.savez
的评论会有所帮助。我很困惑,
pickle vs.np.save/z
等的优缺点是什么?如果在加载和写入
wb
保存时不使用
b
字节读取
rb
,pickle库似乎不会工作,对吗?如果没有它,我会遇到这样的错误:
TypeError:bytes-like-object是必需的,而不是'str'
基本上使用pickle vs-numpy.save/z的主要优点是numpy经过优化,在保存时使用更少的空间?是这样吗?我想知道你关于存储效率的评论是只适用于
np.save
还是也适用于
np.savez
我很困惑,
pickle与np.save/z
的利弊是什么?
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')
# a numpy array

result.importances_mean
array([-1.43651529e-03, -2.73401297e-03,  9.26784059e-05, -7.41427247e-04,
        3.56811863e-03,  2.78035218e-03,  3.70713624e-03,  5.51436515e-03,
        1.16821131e-01,  9.26784059e-05,  9.26784059e-04, -1.80722892e-03,
       -1.71455051e-03, -1.29749768e-03, -9.26784059e-05, -1.43651529e-03,
        0.00000000e+00, -1.11214087e-03, -4.63392030e-05, -4.63392030e-04,
        1.20481928e-03,  5.42168675e-03, -5.56070436e-04,  8.34105653e-04,
       -1.85356812e-04,  0.00000000e+00, -9.73123262e-04, -1.43651529e-03,
       -1.76088971e-03])

# save the array format - np.save(filename.npy, array)

np.save(os.path.join(model_path, "permutation_imp.npy"), result.importances_mean)

# load the array format - np.load(filename.npy)

res = np.load(os.path.join(model_path, "permutation_imp.npy"))
res
array([-1.43651529e-03, -2.73401297e-03,  9.26784059e-05, -7.41427247e-04,
        3.56811863e-03,  2.78035218e-03,  3.70713624e-03,  5.51436515e-03,
        1.16821131e-01,  9.26784059e-05,  9.26784059e-04, -1.80722892e-03,
       -1.71455051e-03, -1.29749768e-03, -9.26784059e-05, -1.43651529e-03,
        0.00000000e+00, -1.11214087e-03, -4.63392030e-05, -4.63392030e-04,
        1.20481928e-03,  5.42168675e-03, -5.56070436e-04,  8.34105653e-04,
       -1.85356812e-04,  0.00000000e+00, -9.73123262e-04, -1.43651529e-03,
       -1.76088971e-03])