如何使用Pandas存储数据框

jef*_*ern 283 python dataframe pandas

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

And*_*den 432

最简单的方法是使用以下方法来腌制to_pickle:

df.to_pickle(file_name)  # where to save it, usually as a .pkl
Run Code Online (Sandbox Code Playgroud)

然后你可以使用以下方法加载它:

df = pd.read_pickle(file_name)
Run Code Online (Sandbox Code Playgroud)

注意:在0.11.1之前save并且load是唯一的方法(它们现在被弃用to_pickle,read_pickle分别赞成和).


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

store = HDFStore('store.h5')

store['df'] = df  # save it
store['df']  # load it
Run Code Online (Sandbox Code Playgroud)

烹饪书中讨论了更高级的策略.


从0.13开始,msgpack也可以更好地实现互操作性,作为JSON的更快替代方案,或者如果你有python对象/文本重量数据(参见这个问题).

  • @geekazoid如果在加载后需要转换数据(即字符串/对象到datetime64),则需要在加载已保存的csv后再次执行此操作,从而导致性能下降.pickle将数据帧保存在当前状态,从而保留数据及其格式.这可以导致大规模的性能提升. (9认同)
  • @geekazoid save被弃用到to_pickle(它创建了一个pickle而不是csv,这是一个更快/更不同的对象). (8认同)
  • pickle和HDFStore都无法保存超过8GB的数据帧.还有替代品吗? (4认同)
  • 只是对此回复的更新。自 Pandas v1.2 起,“HDFStore”方法已重命名为“to_hdf”。 (3认同)
  • @user1700890 尝试从随机数据(文本和数组)生成并发布一个新问题。我不认为这是正确的/怀疑我们遗漏了一些东西。新问题会引起更多关注,但请尝试包含/生成可重现的 DataFrame :) (2认同)

ago*_*old 90

虽然已经有一些答案,但我发现了一个很好的比较,他们尝试了几种方法来序列化Pandas DataFrames:Efficiently Store Pandas DataFrames.

他们比较:

  • pickle:原始的ASCII数据格式
  • cPickle,一个C库
  • pickle-p2:使用较新的二进制格式
  • json:standardlib json库
  • json-no-index:喜欢json,但没有索引
  • msgpack:二进制JSON替代方案
  • CSV
  • hdfstore:HDF5存储格式

在他们的实验中,他们序列化了1,000,000行的DataFrame,其中两列分别进行了测试:一列有文本数据,另一列有数字.他们的免责声明说:

您不应相信以下内容会对您的数据进行推广.您应该查看自己的数据并自己运行基准测试

他们引用的测试源代码可在线获取.由于此代码没有直接工作,我做了一些小的更改,你可以在这里:serialize.py 我得到以下结果:

时间比较结果

他们还提到,通过将文本数据转换为分类数据,序列化速度更快.在他们的测试中大约快10倍(也见测试代码).

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

其他一些参考:

  • 上面链接的博客([Efficiently Store Pandas DataFrames](http://matthewrocklin.com/blog/work/2015/03/16/Fast-Serialization/)似乎已被删除.我自己与`.to_pickle进行了比较()`(使用二进制存储)对`.to_hdf()`(没有压缩).目标是速度,HDF的文件大小是11x Pickle,加载时间是5x Pickle.我的数据是~~ 5k文件〜每行7k行x6列,大多数是数字. (2认同)
  • @Mike Williamson,在我的测试中,pickle的加载速度是HDF的5倍,并且占用磁盘空间的1/11(即hdf在磁盘上大11倍,并且需要5倍的时间从磁盘加载,就像pickle一样).这一切都在python 3上,大熊猫0.22.0. (2认同)

Noa*_*oah 32

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

  1. 您只能加载CSV文件的一部分,pandas.read_csv(..., nrows=1000)只能加载表格的顶部位,而您正在进行开发

  2. 使用ipython进行交互式会话,以便在编辑和重新加载脚本时将pandas表保留在内存中.

  3. 将csv转换为HDF5表

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

您可能也对stackoverflow上的这个答案感兴趣.


Anb*_*ran 17

泡菜很好用!

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
Run Code Online (Sandbox Code Playgroud)

  • 请注意,生成的文件不是csv文件,也许最好使用@Andy Haydens答案中建议的扩展名`.pkl`. (8认同)

小智 10

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

df.to_feather('filename.ft')
Run Code Online (Sandbox Code Playgroud)

  • 然后,“R”可以使用“feather”库直接使用这些数据。 (3认同)

mgo*_*ser 6

Pandas DataFrames 具有to_pickle用于保存 DataFrame 的功能:

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
Run Code Online (Sandbox Code Playgroud)


Mic*_*ner 6

如前所述,有不同的选项和文件格式(HDF5JSONCSVparquetSQL)来存储数据框。但是,pickle不是一等公民(取决于您的设置),因为:

  1. pickle是潜在的安全风险。形成picklePython 文档

警告pickle模块对于错误或恶意构造的数据不安全。永远不要解开从不受信任或未经身份验证的来源收到的数据。

  1. pickle是慢的。在这里这里找到基准。

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