我继承了一些python代码,使用以下代码将其输出保存到pickle:
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
返回一个匹配项。但是当我尝试用这段代码阅读泡菜时:
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'
如何访问泡菜中的其他信息?
更新 是的,我肯定在使用同一个文件。修改后的代码:
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
中的所有其他键)都不应该在文件中。{{1} }, 对?我唯一的另一个想法是,也许在pickle文件头中有什么东西会误导推特者?即也许输出代码被窃听?这是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
答案 0 :(得分:1)
问题是创建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
,然后在触及第二个之前停止。当第一次写入pickle.dump()
来电被注释掉时,unpickling
会正确地返回第二次来电中的dict
。
更新:基于@Mike McKerns的评论&amp;链接,也可以多次调用pickle.load()
来检索同一文件中多个pickle.dump()
调用所产生的多个泡菜。