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


当前回答

如前所述,有不同的选项和文件格式(HDF5, JSON, CSV, parquet, SQL)来存储数据帧。然而,pickle不是一级公民(取决于你的设置),因为:

泡菜是一个潜在的安全隐患。形成pickle的Python文档:

警告pickle模块不安全 恶意构造的数据。对象接收的数据永远不能解pickle 不受信任或未经身份验证的源。

泡菜很慢。找到这里和这里的基准。

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

其他回答

Arctic是一个高性能的Pandas, numpy和其他数值数据的数据存储。它位于MongoDB之上。也许对于OP来说有点过分了,但对于其他无意中看到这篇文章的人来说,值得一提

如前所述,有不同的选项和文件格式(HDF5, JSON, CSV, parquet, SQL)来存储数据帧。然而,pickle不是一级公民(取决于你的设置),因为:

泡菜是一个潜在的安全隐患。形成pickle的Python文档:

警告pickle模块不安全 恶意构造的数据。对象接收的数据永远不能解pickle 不受信任或未经身份验证的源。

泡菜很慢。找到这里和这里的基准。

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

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

我更喜欢使用numpy文件,因为它们快速且易于使用。 下面是一个简单的基准测试,用于保存和加载一个包含100万个点的1列数据框架。

import numpy as np
import pandas as pd

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

使用ipython的%%timeit魔法函数

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

输出为

100 loops, best of 3: 5.97 ms per loop

将数据加载回数据框架

%%timeit
with open('num.npy', 'rb') as np_file:
    data = np.load(np_file)

data_df = pd.DataFrame(data)

输出为

100 loops, best of 3: 5.12 ms per loop

不坏!

CONS

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

这里有很多很棒和充分的答案,但我想发布一个我在Kaggle上使用的测试,这个测试用不同的pandas兼容格式保存和读取大df:

https://www.kaggle.com/pedrocouto39/fast-reading-w-pickle-feather-parquet-jay

我不是作者,也不是作者的朋友,然而,当我读到这个问题时,我觉得值得一提。

CSV: 1分42秒泡菜:4.45秒羽毛:4.35秒拼花:8.31秒杰伦:8.12毫秒 或者0.0812秒(超快的!)

最简单的方法是使用to_pickle来pickle它:

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

然后你可以使用以下命令将其加载回来:

df = pd.read_pickle(file_name)

注意:在0.11.1之前,save和load是唯一的方法(现在它们已被弃用,分别支持to_pickle和read_pickle)。


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

import pandas as pd
store = pd.HDFStore('store.h5')

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

更高级的策略在烹饪书中讨论。


从0.13开始,也有msgpack,它可能在互操作性方面更好,作为JSON的更快替代品,或者如果你有python对象/文本较多的数据(参见这个问题)。