【问题标题】:What is the fastest way to serialize a DataFrame besides to_pickle?除了 to_pickle 之外,序列化 DataFrame 的最快方法是什么?
【发布时间】:2013-11-23 17:39:59
【问题描述】:

我需要序列化 ​​DataFrame 并通过网络发送它们。出于安全原因,我不能使用 pickle。

下一个最快的方法是什么?我对 v0.13 中的 msgpacks 很感兴趣,但除非我做错了什么,否则性能似乎比 pickle 差得多。

In [107]: from pandas.io.packers import pack

In [108]: df = pd.DataFrame(np.random.rand(1000, 100))

In [109]: %timeit buf = pack(df)
100 loops, best of 3: 15.5 ms per loop

In [110]: import pickle

In [111]: %timeit buf = pickle.dumps(df)
1000 loops, best of 3: 241 µs per loop

到目前为止,我发现的最好的方法就是使用 array.tostring() 序列化同质 numpy 数组(df.as_blocks() 很方便)并从中重建 DataFrame。性能堪比泡菜。

但是,使用这种方法,我不得不将 dtype=object 的列(即任何至少有一个字符串的列)转换为完全字符串,因为 Numpy 的 fromstring() 无法反序列化 dtype=object。 Pickle 设法在对象列中保留混合类型(它似乎在 pickle 输出中包含了一些功能)。

【问题讨论】:

    标签: python serialization numpy pandas pickle


    【解决方案1】:

    现在这与这个 PR 相当有竞争力:https://github.com/pydata/pandas/pull/5498(不久将合并到 0.13)

    In [1]: from pandas.io.packers import pack
    
    In [2]: import cPickle as pkl
    
    In [3]: df = pd.DataFrame(np.random.rand(1000, 100))
    

    上面的例子

    In [6]: %timeit buf = pack(df)
    1000 loops, best of 3: 492 µs per loop
    
    In [7]: %timeit buf = pkl.dumps(df,pkl.HIGHEST_PROTOCOL)
    1000 loops, best of 3: 681 µs per loop
    

    更大的框架

    In [8]: df = pd.DataFrame(np.random.rand(100000, 100))
    
    In [9]:  %timeit buf = pack(df)
    10 loops, best of 3: 192 ms per loop
    
    In [10]: %timeit buf = pkl.dumps(df,pkl.HIGHEST_PROTOCOL)
    10 loops, best of 3: 119 ms per loop
    

    另一种选择是使用内存中的 hdf 文件

    请看这里:http://pytables.github.io/cookbook/inmemory_hdf5_files.html; pandas 尚不支持添加驱动程序 arg(可以通过很简单的猴子补丁来完成)。

    另一种可能是ctable,请参阅https://github.com/FrancescAlted/carray。不过 pandas ATM 尚不支持。

    【讨论】:

    • 非常感谢杰夫。我修补了 HDFStore 中的 open() 方法。对于我通常使用的大小,我仍然看到内存中 to_pickle() 和内存中 to_hdf() 之间存在很大差异。有人提出的另一个建议是自己重用 reducesetstate 方法。你知道我怎样才能从 reduce 返回值返回到一个对象吗?
    • 如果 picklie/in memory hdf 之间的差异确实很重要,那么您将归结为函数调用,这不值得优化。只需将框架拆开并使用 numpy.tostring。处理小尺寸和大尺寸是两个不同的问题。如果您想了解有关 reduce 的更多信息,则必须深入研究代码。
    • 我更新了...看看我发布的 PR。这应该基本上可以解决问题了。
    • 这太棒了。非常感谢,杰夫。 (你是 jreback 吗?如果是这样,感谢你在 pandas 上所做的所有工作。)我搞砸了 np.array.tostring(),但它不能很好地处理 dtype=object。总的来说,你认为 msgpack 格式会继续受到 pandas 的喜爱吗?
    • 是的..那是我....我最初把 msgpack 放进去了(我们已经对它进行了 cythonized 以提供动力)。我认为它在未来会非常有用。这就是想法,本质上是泡菜的“替代品”。
    猜你喜欢
    • 2017-12-11
    • 2010-12-27
    • 2013-06-13
    • 2013-03-29
    • 2021-01-06
    • 2013-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多