如何利用python读取PKL文件

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何利用python读取PKL文件相关的知识,希望对你有一定的参考价值。

参考技术A import cPickle

inf=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格式文件

python中,使用 'ab'方式写入,使用'rb'读出,为啥无法读出全部内容?

如何利用Python程序读取Excel创建折线图

如何解压pkl文件?

如何利用rapidjson修改json文件

标注数据读取与存储案例:xml读取本地文件存储到pkl