Python pickle 的元素似乎缺失
Elements of a Python pickle seem to be missing
我继承了一些 python 代码,使用以下代码将其输出保存到泡菜中:
def save_picklefile_and_close(self):
pickle.dump({'p_index': self.p_index, 'p_val': self.p_val,
'z': self.z, 'w': self.w, 'nd': self.nd, 'nfg': self.nfg,
'lamb_scalar': self.lamb_scalar, 'PEAKSIZE': self.PEAKSIZE,
'N': self.N, 'S': self.S, 'F': self.F,
'FG': self.FG, 'q': self.q,
'pi': self.pi, 'phi': self.phi,
'p_scores': self.p_scores, 'w_scores': self.w_scores, 'z_scores': self.z_scores,
'likelihood': self.likelihood,
'p_true_val': self.p_true_val,
'p_true_index': self.p_true_index,
'w_true': self.w_true,
'phi_true': self.phi_true,
'pi_true': self.pi_true,
'z_true': self.z_true,
'z_true_per_data': self.z_true_per_data,
'data_for_debugging': self.data_for_debugging,
}, self.picklefile)
self.picklefile.close()
这在我看来就像是腌制的字典,网上有很多例子。所有的键都在 pickle 文件中,例如grep 'w_true' file.p
returns 一场比赛。但是当我尝试用这段代码阅读泡菜时:
f = open('file.p')
p = pickle.load(f)
print "type=", type(p)
print "shape=", p.shape
print "w_true=", p.w_true
我得到的只是一个 numpy.ndarray
:
type= <type 'numpy.ndarray'>
shape= (56, 147)
w_true=
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-39-83ddd085f0fd> in <module>()
3 print "type=", type(p)
4 print "shape=", p.shape
----> 5 print "w_true=", p.w_true
AttributeError: 'numpy.ndarray' object has no attribute 'w_true'
如何访问 pickle 中的其他信息?
更新:
是的,我肯定在使用同一个文件。本次修改代码:
f = open('/path/to/file.p', mode='rt')
p = pickle.load(f)
print "type=", type(p)
print "shape=", p.shape
i = 0
for line in f:
if 'w_true' in line:
print "line no.", i, ":", line
i += 1
结果:
type= <type 'numpy.ndarray'>
shape= (56, 147)
line no. 7499 : sS'w_true'
但是没有理由字符串 w_true
(以及 dict
中的所有其他键)应该在文件中,如果它是 只有 一个 ndarray
,对吧?我唯一的另一个想法是,也许 pickle 文件头中有什么东西误导了 unpickler? IE。也许输出代码有问题?这是 file.p
的头像:
$ head -n25 file.p
cnumpy.core.multiarray
_reconstruct
p1
(cnumpy
ndarray
p2
(I0
tS'b'
tRp3
(I1
(I56
I147
tcnumpy
dtype
p4
(S'i4'
I0
I1
tRp5
(I3
S'<'
NNNI-1
I-1
I0
tbI00
问题是创建 pickle 的代码只打开了一个文件:
self.picklefile = open(picklefile_name, 'wb')
然后两次写入同一个文件。首先在这里:
if self.is_saving_pickle:
pickle.dump(self.x, self.picklefile) #a single numpy.ndarray
然后稍后在这里:
def save_picklefile_and_close(self):
pickle.dump({'p_index': self.p_index, 'p_val': self.p_val,
# ... snip ...
'data_for_debugging': self.data_for_debugging,
}, self.picklefile)
self.picklefile.close()
当 unpickler
开始加载 file.p
时,它看到并返回了第一个 pickle
,然后在接触第二个之前停止了。当第一个 write pickle.dump()
调用被注释掉时,unpickling
正确 returns 来自第二个调用的 dict
。
更新: 根据@Mike McKerns 的评论和链接,也可以多次调用 pickle.load()
来检索多个 [=16] 制作的泡菜=] 在同一个文件中调用。
我继承了一些 python 代码,使用以下代码将其输出保存到泡菜中:
def save_picklefile_and_close(self):
pickle.dump({'p_index': self.p_index, 'p_val': self.p_val,
'z': self.z, 'w': self.w, 'nd': self.nd, 'nfg': self.nfg,
'lamb_scalar': self.lamb_scalar, 'PEAKSIZE': self.PEAKSIZE,
'N': self.N, 'S': self.S, 'F': self.F,
'FG': self.FG, 'q': self.q,
'pi': self.pi, 'phi': self.phi,
'p_scores': self.p_scores, 'w_scores': self.w_scores, 'z_scores': self.z_scores,
'likelihood': self.likelihood,
'p_true_val': self.p_true_val,
'p_true_index': self.p_true_index,
'w_true': self.w_true,
'phi_true': self.phi_true,
'pi_true': self.pi_true,
'z_true': self.z_true,
'z_true_per_data': self.z_true_per_data,
'data_for_debugging': self.data_for_debugging,
}, self.picklefile)
self.picklefile.close()
这在我看来就像是腌制的字典,网上有很多例子。所有的键都在 pickle 文件中,例如grep 'w_true' file.p
returns 一场比赛。但是当我尝试用这段代码阅读泡菜时:
f = open('file.p')
p = pickle.load(f)
print "type=", type(p)
print "shape=", p.shape
print "w_true=", p.w_true
我得到的只是一个 numpy.ndarray
:
type= <type 'numpy.ndarray'>
shape= (56, 147)
w_true=
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-39-83ddd085f0fd> in <module>()
3 print "type=", type(p)
4 print "shape=", p.shape
----> 5 print "w_true=", p.w_true
AttributeError: 'numpy.ndarray' object has no attribute 'w_true'
如何访问 pickle 中的其他信息?
更新: 是的,我肯定在使用同一个文件。本次修改代码:
f = open('/path/to/file.p', mode='rt')
p = pickle.load(f)
print "type=", type(p)
print "shape=", p.shape
i = 0
for line in f:
if 'w_true' in line:
print "line no.", i, ":", line
i += 1
结果:
type= <type 'numpy.ndarray'>
shape= (56, 147)
line no. 7499 : sS'w_true'
但是没有理由字符串 w_true
(以及 dict
中的所有其他键)应该在文件中,如果它是 只有 一个 ndarray
,对吧?我唯一的另一个想法是,也许 pickle 文件头中有什么东西误导了 unpickler? IE。也许输出代码有问题?这是 file.p
的头像:
$ head -n25 file.p
cnumpy.core.multiarray
_reconstruct
p1
(cnumpy
ndarray
p2
(I0
tS'b'
tRp3
(I1
(I56
I147
tcnumpy
dtype
p4
(S'i4'
I0
I1
tRp5
(I3
S'<'
NNNI-1
I-1
I0
tbI00
问题是创建 pickle 的代码只打开了一个文件:
self.picklefile = open(picklefile_name, 'wb')
然后两次写入同一个文件。首先在这里:
if self.is_saving_pickle:
pickle.dump(self.x, self.picklefile) #a single numpy.ndarray
然后稍后在这里:
def save_picklefile_and_close(self):
pickle.dump({'p_index': self.p_index, 'p_val': self.p_val,
# ... snip ...
'data_for_debugging': self.data_for_debugging,
}, self.picklefile)
self.picklefile.close()
当 unpickler
开始加载 file.p
时,它看到并返回了第一个 pickle
,然后在接触第二个之前停止了。当第一个 write pickle.dump()
调用被注释掉时,unpickling
正确 returns 来自第二个调用的 dict
。
更新: 根据@Mike McKerns 的评论和链接,也可以多次调用 pickle.load()
来检索多个 [=16] 制作的泡菜=] 在同一个文件中调用。