关于python:如何使用Pandas存储数据帧

How to store a dataframe using Pandas

现在,每次运行脚本时,我都要导入一个相当大的CSV作为数据帧。是否有一个好的解决方案可以在运行之间保持数据帧始终可用,这样我就不必花费所有时间等待脚本运行?


最简单的方法是用to_pickle腌制:

1
df.to_pickle(file_name)  # where to save it, usually as a .pkl

然后您可以使用以下方法重新加载:

1
df = pd.read_pickle(file_name)

注:在0.11.1之前,只有saveload两种方法可以做到这一点(现在,它们分别被否决,赞成to_pickleread_pickle)。

另一个流行的选择是使用hdf5(pytables),它为大型数据集提供了非常快的访问时间:

1
2
3
4
store = HDFStore('store.h5')

store['df'] = df  # save it
store['df']  # load it

更先进的策略将在食谱中讨论。

由于0.13,还有MSGPack,它可能更好地实现互操作性,作为JSON的更快替代,或者如果您有Python对象/文本重数据(请参见本问题)。


虽然已经有了一些答案,但我发现了一个很好的比较,他们尝试了几种方法来序列化熊猫数据帧:高效地存储熊猫数据帧。

他们比较:

  • pickle:原始ASCII数据格式
  • C图书馆
  • pickle-p2:使用新的二进制格式
  • json:standardlib json库
  • JSON没有索引:像JSON,但是没有索引
  • msgpack:二进制JSON替代方案
  • 猪瘟病毒
  • hdfstore:hdf5存储格式

在他们的实验中,他们对一个包含1000000行的数据帧进行了序列化,其中两列分别进行了测试:一列使用文本数据,另一列使用数字。他们的免责声明说:

You should not trust that what follows generalizes to your data. You should look at your own data and run benchmarks yourself

他们所引用的测试的源代码可以在线获得。由于这段代码不能直接工作,我做了一些小的更改,您可以在这里得到:serialize.py我得到了以下结果:

time comparison results

他们还提到,随着文本数据到分类数据的转换,序列化速度要快得多。在他们的测试中,速度大约是测试代码的10倍。

编辑:pickle的时间高于csv的时间可以用所用的数据格式来解释。默认情况下,pickle使用可打印的ASCII表示,它生成更大的数据集。然而,从图中可以看出,使用新的二进制数据格式(版本2,pickle-p2的pickle)的加载时间要短得多。

其他参考文献:

  • 在阅读csv文件最快的python库的问题中,有一个非常详细的答案,它将不同的库与阅读csv文件的基准进行了比较。结果是读取csv文件的速度最快。
  • 另一个序列化测试显示msgpack python、ujson和cpickle是序列化中最快的。


如果我理解正确的话,您已经在使用pandas.read_csv(),但是希望加快开发过程,这样您就不必每次编辑脚本时都加载文件了,对吗?我有一些建议:

  • 在开发过程中,您可以使用pandas.read_csv(..., nrows=1000)只加载部分csv文件,以只加载表的顶部。

  • 在交互式会话中使用ipython,这样在编辑和重新加载脚本时,就可以将pandas表保存在内存中。

  • 将csv转换为hdf5表

  • 更新后使用DataFrame.to_feather()pd.read_feather()以超快速的R兼容羽毛二进制格式存储数据(在我手中,数字数据比pandas.to_pickle()稍快,字符串数据比pandas.to_pickle()快得多)。

  • 您也可能对stackoverflow的这个答案感兴趣。


    泡菜很好用!

    1
    2
    3
    import pandas as pd
    df.to_pickle('123.pkl')    #to save the dataframe, df to 123.pkl
    df1 = pd.read_pickle('123.pkl') #to load 123.pkl back to the dataframe df


    熊猫数据帧具有to_pickle功能,可用于保存数据帧:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    import pandas as pd

    a = pd.DataFrame({'A':[0,1,0,1,0],'B':[True, True, False, False, False]})
    print a
    #    A      B
    # 0  0   True
    # 1  1   True
    # 2  0  False
    # 3  1  False
    # 4  0  False

    a.to_pickle('my_file.pkl')

    b = pd.read_pickle('my_file.pkl')
    print b
    #    A      B
    # 0  0   True
    # 1  1   True
    # 2  0  False
    # 3  1  False
    # 4  0  False

    您可以使用羽毛格式文件。它非常快。

    1
    df.to_feather('filename.ft')


    numpy文件格式对于数字数据来说非常快

    我更喜欢使用numpy文件,因为它们既快又容易使用。这是一个简单的保存和加载数据帧的基准,其中有1列100万点。

    1
    2
    3
    4
    5
    import numpy as np
    import pandas as pd

    num_dict = {'voltage': np.random.rand(1000000)}
    num_df = pd.DataFrame(num_dict)

    使用ipython的%%timeit魔力函数

    1
    2
    3
    %%timeit
    with open('num.npy', 'wb') as np_file:
        np.save(np_file, num_df)

    输出是

    1
    100 loops, best of 3: 5.97 ms per loop

    将数据加载回数据帧

    1
    2
    3
    4
    5
    %%timeit
    with open('num.npy', 'rb') as np_file:
        data = np.load(np_file)

    data_df = pd.DataFrame(data)

    输出是

    1
    100 loops, best of 3: 5.12 ms per loop

    不错!

    欺骗

    如果使用python 2保存numpy文件,然后尝试使用python 3打开(反之亦然),则会出现问题。


    如前所述,存储数据帧有不同的选项和文件格式(hdf5、json、csv、parquet、sql)。但是,不应该出现在名单上的是pickle

    1)pickle是一种潜在的安全风险。形成pickle的python文档:

    Warning The pickle module is not secure against erroneous or
    maliciously constructed data. Never unpickle data received from an
    untrusted or unauthenticated source.

    2)pickle慢。在这里和这里找到基准点。

    根据您的设置/使用情况,这两个限制都不适用,但我不建议将pickle作为熊猫数据帧的默认持久性。


    https://docs.python.org/3/library/pickle.html网站

    pickle协议格式:

    协议版本0是原始的"人类可读"协议,与早期版本的Python向后兼容。

    协议版本1是一种旧的二进制格式,它也与早期版本的python兼容。

    python 2.3中引入了协议版本2。它提供了更有效的新类酸洗。有关方案2所带来的改进的信息,请参阅PEP 307。

    在python 3.0中添加了协议版本3。它对bytes对象有明确的支持,不能被python 2.x解包。这是默认协议,当需要与其他python 3版本兼容时,建议使用该协议。

    在python 3.4中添加了协议版本4。它增加了对非常大的对象的支持、对更多类型的对象的清除以及一些数据格式优化。关于方案4所带来的改进的信息,请参阅PEP 3154。


    1
    2
    3
    4
    5
    6
    7
    import pickle

    example_dict = {1:"6",2:"2",3:"g"}

    pickle_out = open("dict.pickle","wb")
    pickle.dump(example_dict, pickle_out)
    pickle_out.close()

    以上代码将保存pickle文件

    1
    2
    pickle_in = open("dict.pickle","rb")
    example_dict = pickle.load(pickle_in)

    这两行将打开保存的pickle文件