如何利用python读取PKL文件
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何利用python读取PKL文件相关的知识,希望对你有一定的参考价值。
参考技术A import cPickleinf=cPickle.load(open(r'文件路径','rb'))
print inf
f.close()
之前利用百度的来的语句总是会出错,捣鼓一阵后解决了报错问题
如出现以上错误,在路径前加'r'就可解决报错。
如出现以上错误,在路径后面加‘rb’就可解决报错。
Python,奇怪的内存消耗行为
【中文标题】Python,奇怪的内存消耗行为【英文标题】:Python, weird memory consumption behavior 【发布时间】:2018-05-01 10:11:16 【问题描述】:我有一个包含数千个.pkl
文件的文件夹,每个文件都包含一个对象元组列表。较大的文件为 8 Gb,较小的文件为 1 kB(空列表)。我正在遍历文件并单独加载每个 .pkl。因此,我应该得到的最大内存消耗应该是更大的.pkl
文件。但是,它达到了 65 Gb 的 RAM,我不知道为什么...
在下面的代码中,我提供了创建和读取 pickle 文件的函数,以及我在特定文件夹上调用的绘图函数。我没有提供所有使用的功能,但它们不应该是这个问题背后的原因。
原因:PB等函数只对文件名、字符串起作用。 => 低内存消耗。 PB 只是一个值,因此列表距离不应太大。
import os
import _pickle as pickle
from matplotlib import pyplot as plt
def write_solutions(solutions, folder_path, file_name):
"""
Function write a pickle file out of the solutions list.
This function overwrites any existing file.
"""
with open(join(folder_path, file_name), "wb") as output:
pickle.dump(solutions, output, -1)
def read_solutions(folder_path, file_name):
"""
Function reading a pickle file and returning the solutions list.
"""
with open(join(folder_path, file_name), "rb") as input:
solutions = pickle.load(input)
return solutions
def plotting_solution_space_line_detailed(folder, output, N, max_pb, files = None):
"""
Function taking .pkl in input and plotting.
"""
if files == None:
# Load all the .pkl files
files = os.listdir(folder)
files = [elt for elt in files if elt[len(elt)-4:] == ".pkl"]
data = dict()
for i in range(2, N+1):
data[i] = [list(), list(), list(), list(), list(), list()]
for file in files:
item = read_solutions(folder, file)
nfo = file_name_reader(file)
n = len(nfo[0])
desired_pb = PB(file)
if len(item) == 0:
data[n][3].append(1)
data[n][2].append(desired_pb)
else:
data[n][1].append(1.1)
data[n][0].append(desired_pb)
# Computation of the actual closest PB
distance = [abs(PB(file_namer(elt[0])) - desired_pb) for elt in item]
i = distance.index(min(distance))
plot_sol = item[i][0]
actual_pb = PB(file_namer(plot_sol))
# Plot of the acutal PB
data[n][5].append(1.2)
data[n][4].append(actual_pb)
empty = list()
for i in range(2, N+1):
if len(data[i][0]) == 0 and len(data[i][2]) == 0:
empty.append(i)
for elt in empty:
del data[elt]
# Creates the figure
f, ax = plt.subplots(len(data), sharex=True, sharey=True, figsize=(10,5))
f.subplots_adjust(hspace=0)
plt.setp([a.get_xticklabels() for a in f.axes[:-1]], visible=False)
for a in f.axes:
a.tick_params(
axis='y', # changes apply to the x-axis
which='both', # both major and minor ticks are affected
left='False',
right='False',
labelleft='False') # labels along the left edge are off
# Shrink the axes
box = a.get_position()
a.set_position([box.x0, box.y0, box.width * 0.9, box.height])
# Add a vertical line at the max budget
a.axvline(x=max_pb, linestyle= '--',lw = 0.4, color = "black")
if len(data) > 1:
for i in range(len(data)):
key = list(data.keys())[i]
X = data[key][0]
Y = data[key][1]
X2 = data[key][2]
Y2 = data[key][3]
X3 = data[key][4]
Y3 = data[key][5]
ax[i].scatter(X, Y, s = 3)
ax[i].scatter(X2, Y2, s = 3, color = "crimson")
ax[i].scatter(X3, Y3, s = 3, color = "teal")
ax[i].set_ylim(0.8, 1.4)
ax[i].set_ylabel(" Signals".format(key))
ax[i].text(1.01, 0.6, "Nb with solution(s):\n".format(len(X)), fontsize=8, transform=ax[i].transAxes)
ax[i].text(1.01, 0.2, "Nb without solution(s):\n".format(len([x for x in X2 if x <= max_pb])), fontsize=8, transform=ax[i].transAxes)
else:
key = list(data.keys())[0]
X = data[key][0]
Y = data[key][1]
X2 = data[key][2]
Y2 = data[key][3]
X3 = data[key][4]
Y3 = data[key][5]
ax.scatter(X, Y, s = 3)
ax.scatter(X2, Y2, s = 3, color = "crimson")
ax.scatter(X3, Y3, s = 3, color = "teal")
ax.set_ylim(0.8, 1.4)
ax.set_ylabel(" Signals".format(key))
ax.text(1.01, 0.6, "Nb solutions:\n".format(len(X)), fontsize=12, transform=ax.transAxes)
ax.text(1.01, 0.2, "Nb no solutions:\n".format(len([x for x in X2 if x <= max_pb])), fontsize=8, transform=ax.transAxes)
f.text(0.5, 0.94, 'Solution space', ha='center')
f.text(0.5, 0.04, 'PB', ha='center')
f.text(0.04, 0.5, 'Number of signals', va='center', rotation='vertical')
plt.savefig(".png".format(output), dpi = 500)
plt.close()
您是否看到.pkl
文件如此高内存消耗的任何原因。一旦在 RAM 中解压,它就不会被压缩吗?还是其他问题?
【问题讨论】:
你已经看过这个问题了吗? ***.com/questions/13871152/why-pickle-eat-memory @ChatterOne 好吧,这很简单……我不知道我是如何通过那个帖子的。非常感谢您指出 x') 另外,正如另一个问题的 cmets 中所建议的,您可以查看 github.com/pgbovine/streaming-pickle ,它允许您从泡菜中一一读取元素,而不是将它们全部加载到内存中同时。 @ChatterOne 实际上,当我编写程序时,我并不知道这种可能性......它会引起巨大的变化,但可能是一个解决方案:/ @ChatterOne 顺便说一句,您给我的链接似乎很旧。代码总是引发 TypeError(即使有给定的示例):write() 参数必须是 str,而不是字节。 【参考方案1】:您的错误是假设大小相等。泡菜中的整数比所需的字节多一点。但是内存中的整数大约是 28 个字节(小数的一些例外是不可承受的)。
这就是为什么通常人们会使用 numpy 来保存数据的原因,因为它是固定大小的数字类型的紧凑数组。
【讨论】:
我的文件存储这些数据:[(S1, S2, S3), (S4, S5, S6), ..., (S7, S8, S9)]
其中S
是定制对象。知道每个文件包含 1 个列表,并且该列表可以是空的,或者由数千(百万)个对象 S
的元组组成,您将如何有效地存储这些数据?我可能会选择 HDF5 而不是 pickle。希望我现在有一台功能强大的 PC,可以打开大型 .pkl 文件(RAM 中 8 GB => 65 GB),但这很快就会给我带来问题......
由于我不知道 S 的构成,我无法评论它的不同表现。
顺便说一句,HDF5 不会影响这一点。由于其他原因(例如版本兼容性等),它可能是比 pickle 更好的选择,但如果您的内部对象看起来相同,它们需要相同的内存。
对于S对象,大约有10个属性是int和floats,1个是floats的列表。我同意 HDF5 它不会影响磁盘上的内存,但它应该会影响 RAM 中的内存(这是我遇到的问题)。参考文献ChatterOne 发表评论。
如果pickle在加载过程中增加了更多的开销,这很公平。生成的对象将是相同的。如果列表是固定大小的或至少有一个上限,则可以将所有状态表示为浮点向量。以上是关于如何利用python读取PKL文件的主要内容,如果未能解决你的问题,请参考以下文章
python 保存训练好的预测模型 python如何加载训练好的模型pkl格式文件