如何可逆地将 Pandas 数据框存储到磁盘或从磁盘加载

2025-02-18 09:23:00
admin
原创
149
摘要:问题描述:现在,CSV每次运行脚本时,我都会导入一个相当大的数据框。有没有一个好的解决方案可以让这个数据框在运行之间始终可用,这样我就不必花费那么多时间等待脚本运行?解决方案 1:最简单的方法是使用以下方法进行腌制to_pickle:df.to_pickle(file_name) # where to sa...

问题描述:

现在,CSV每次运行脚本时,我都会导入一个相当大的数据框。有没有一个好的解决方案可以让这个数据框在运行之间始终可用,这样我就不必花费那么多时间等待脚本运行?


解决方案 1:

最简单的方法是使用以下方法进行腌制to_pickle

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

然后您可以使用以下方式加载它:

df = pd.read_pickle(file_name)

注意:在 0.11.1 之前saveload是执行此操作的唯一方法(它们现在已被弃用,取而代之的是to_pickleread_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 对象/文本密集型数据(请参阅这个问题)。

解决方案 2:

虽然已经有一些答案,但我发现一个很好的比较,其中他们尝试了几种方法来序列化 Pandas DataFrames:有效地存储 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 倍(另请参阅测试代码)。

编辑:pickle 比 CSV 耗时更长,这可以通过所使用的数据格式来解释。默认情况下,pickle使用可打印的 ASCII 表示,这会生成更大的数据集。但是从图中可以看出,使用较新的二进制数据格式(版本 2,pickle-p2)的 pickle 的加载时间要短得多。

其他一些参考资料:

  • 在“读取 CSV 文件最快的 Python 库”问题中,有一个非常详细的答案,它使用基准比较了不同的库来读取 csv 文件。结果是读取 csv 文件numpy.fromfile最快的是哪个。

  • 另一项序列化测试
    表明msgpack,ujson和 cPickle 的序列化速度最快。

解决方案 3:

如果我理解正确的话,您已经在使用了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 上的这个答案感兴趣。

解决方案 4:

泡菜效果很好!

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

解决方案 5:

您可以使用feather格式的文件。它非常快。

df.to_feather('filename.ft')

解决方案 6:

如前所述,有多种选项和文件格式(HDF5、JSON、CSV、parquet、SQL)可用于存储数据框。但是,pickle它并不是最佳选择(取决于您的设置),因为:

  1. pickle存在潜在的安全风险。参见pickle 的 Python 文档:

警告pickle模块无法抵御错误或恶意构建的数据。切勿对来自不受信任或未经身份验证的来源的数据进行反解析。

  1. pickle很慢。在此处和此处查看基准测试。

  2. pickle仅适用于 Python。您不能简单地使用其他工具或编程语言读取结果。

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

解决方案 7:

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

解决方案 8:

Numpy 文件格式对于数值数据来说速度非常快

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

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

不错!

缺点

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

解决方案 9:

另一项相当新鲜的测试to_pickle()

我总共有25 个 文件需要处理,最终大约包含200 万个项目。.csv`dataframe`

(注意:除了加载 .csv 文件之外,我还处理一些数据并通过新列扩展数据框。)

浏览所有25 个 .csv 文件并创建数据框大约需要14 sec

从文件加载整个数据框pkl需要不到1 sec

解决方案 10:

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

pickle 协议格式:

协议版本 0 是原始的“人类可读”协议,并且向后兼容早期版本的 Python。

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

协议版本 2 是在 Python 2.3 中引入的。它提供了更高效的新式类 pickling。有关协议 2 带来的改进的信息,请参阅 PEP 307。

协议版本 3 是在 Python 3.0 中添加的。它明确支持字节对象,并且无法被 Python 2.x 取消封存。这是默认协议,也是需要与其他 Python 3 版本兼容时的推荐协议。

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

解决方案 11:

Arctic是用于 Pandas、numpy 和其他数字数据的高性能数据存储。它位于 MongoDB 之上。对于 OP 来说可能有点过分,但对于偶然发现这篇文章的其他人来说,值得一提

解决方案 12:

pyarrow 跨版本兼容性

总体而言,已经转移到 pyarrow/feather(pandas/msgpack 的弃用警告)。但是,我在使用 pyarrow 时遇到了一个问题,即使用 pyarrow 0.15.1序列化的数据无法使用 0.16.0 ARROW-7961进行反序列化。我使用序列化来使用 redis,因此必须使用二进制编码。

我重新测试了各种选项(使用 jupyter notebook)

import sys, pickle, zlib, warnings, io
class foocls:
    def pyarrow(out): return pa.serialize(out).to_buffer().to_pybytes()
    def msgpack(out): return out.to_msgpack()
    def pickle(out): return pickle.dumps(out)
    def feather(out): return out.to_feather(io.BytesIO())
    def parquet(out): return out.to_parquet(io.BytesIO())

warnings.filterwarnings("ignore")
for c in foocls.__dict__.values():
    sbreak = True
    try:
        c(out)
        print(c.__name__, "before serialization", sys.getsizeof(out))
        print(c.__name__, sys.getsizeof(c(out)))
        %timeit -n 50 c(out)
        print(c.__name__, "zlib", sys.getsizeof(zlib.compress(c(out))))
        %timeit -n 50 zlib.compress(c(out))
    except TypeError as e:
        if "not callable" in str(e): sbreak = False
        else: raise
    except (ValueError) as e: print(c.__name__, "ERROR", e)
    finally: 
        if sbreak: print("=+=" * 30)        
warnings.filterwarnings("default")

我的数据框的结果如下(在outjupyter 变量中)

pyarrow before serialization 533366
pyarrow 120805
1.03 ms ± 43.9 µs per loop (mean ± std. dev. of 7 runs, 50 loops each)
pyarrow zlib 20517
2.78 ms ± 81.8 µs per loop (mean ± std. dev. of 7 runs, 50 loops each)
=+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+=
msgpack before serialization 533366
msgpack 109039
1.74 ms ± 72.8 µs per loop (mean ± std. dev. of 7 runs, 50 loops each)
msgpack zlib 16639
3.05 ms ± 71.7 µs per loop (mean ± std. dev. of 7 runs, 50 loops each)
=+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+=
pickle before serialization 533366
pickle 142121
733 µs ± 38.3 µs per loop (mean ± std. dev. of 7 runs, 50 loops each)
pickle zlib 29477
3.81 ms ± 60.4 µs per loop (mean ± std. dev. of 7 runs, 50 loops each)
=+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+=
feather ERROR feather does not support serializing a non-default index for the index; you can .reset_index() to make the index into column(s)
=+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+=
parquet ERROR Nested column branch had multiple children: struct<x: double, y: double>
=+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+=

feather 和 parquet 不适用于我的数据框。我将继续使用 pyarrow。不过,我将补充 pickle(无压缩)。写入缓存时,存储 pyarrow 和 pickle 序列化形式。从缓存读取时,如果 pyarrow 反序列化失败,则回退到 pickle。

解决方案 13:

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 文件

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

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

解决方案 14:

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

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

我不是这篇文章的作者或作者的朋友,但是,当我读到这个问题时,我认为值得一提。

CSV:1 分 42 秒 Pickle:4.45 秒 Feather:4.35 秒 Parquet:8.31 秒 Jay:8.12 毫秒或 0.0812 秒(速度超快!)

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   3970  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   2740  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Freshdesk、ClickUp、nTask、Hubstaff、Plutio、Productive、Targa、Bonsai、Wrike。在当今快速变化的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多企业在项目管理过程中面临着诸多痛点,如任务分配不...
项目管理系统   79  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Monday、TeamGantt、Filestage、Chanty、Visor、Smartsheet、Productive、Quire、Planview。在当今快速变化的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多项目经理和团队在管理复杂项目时,常...
开源项目管理工具   87  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Smartsheet、GanttPRO、Backlog、Visor、ResourceGuru、Productive、Xebrio、Hive、Quire。在当今快节奏的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多企业在选择项目管理工具时常常面临困惑:...
项目管理系统   74  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用