如何在 hdf5 中有效地保存 python pandas 数据帧并将其作为 R 中的数据帧打开?

Posted

技术标签:

【中文标题】如何在 hdf5 中有效地保存 python pandas 数据帧并将其作为 R 中的数据帧打开?【英文标题】:How can I efficiently save a python pandas dataframe in hdf5 and open it as a dataframe in R? 【发布时间】:2012-08-29 23:46:18 【问题描述】:

我认为标题涵盖了这个问题,但要说明:

pandas python 包有一个 DataFrame 数据类型,用于在 python 中保存表数据。它还具有hdf5 文件格式的便捷接口,因此可以使用类似字典的简单接口(假设您安装了pytables)来保存pandas DataFrame(和其他数据)

import pandas 
import numpy
d = pandas.HDFStore('data.h5')
d['testdata'] = pandas.DataFrame('N': numpy.random.randn(5))
d.close()

到目前为止一切顺利。但是,如果我尝试将相同的 hdf5 加载到 R 中,我会发现事情并不那么简单:

> library(hdf5)
> hdf5load('data.h5')
NULL
> testdata
$block0_values
         [,1]      [,2]      [,3]       [,4]      [,5]
[1,] 1.498147 0.8843877 -1.081656 0.08717049 -1.302641
attr(,"CLASS")
[1] "ARRAY"
attr(,"VERSION")
[1] "2.3"
attr(,"TITLE")
[1] ""
attr(,"FLAVOR")
[1] "numpy"

$block0_items
[1] "N"
attr(,"CLASS")
[1] "ARRAY"
attr(,"VERSION")
[1] "2.3"
attr(,"TITLE")
[1] ""
attr(,"FLAVOR")
[1] "numpy"
attr(,"kind")
[1] "string"
attr(,"name")
[1] "N."

$axis1
[1] 0 1 2 3 4
attr(,"CLASS")
[1] "ARRAY"
attr(,"VERSION")
[1] "2.3"
attr(,"TITLE")
[1] ""
attr(,"FLAVOR")
[1] "numpy"
attr(,"kind")
[1] "integer"
attr(,"name")
[1] "N."

$axis0
[1] "N"
attr(,"CLASS")
[1] "ARRAY"
attr(,"VERSION")
[1] "2.3"
attr(,"TITLE")
[1] ""
attr(,"FLAVOR")
[1] "numpy"
attr(,"kind")
[1] "string"
attr(,"name")
[1] "N."

attr(,"TITLE")
[1] ""
attr(,"CLASS")
[1] "GROUP"
attr(,"VERSION")
[1] "1.0"
attr(,"ndim")
[1] 2
attr(,"axis0_variety")
[1] "regular"
attr(,"axis1_variety")
[1] "regular"
attr(,"nblocks")
[1] 1
attr(,"block0_items_variety")
[1] "regular"
attr(,"pandas_type")
[1] "frame"

这让我想到了我的问题:理想情况下,我能够从 R 到 pandas 来回保存。我显然可以写一个从 pandas 到 R 的包装器(我认为......虽然我认为如果我使用 pandas MultiIndex 可能会变得更棘手),但我认为我不能轻易地在 pandas 中使用该数据。有什么建议吗?

奖励:我真正想要做的是将 R 中的 data.table 包与 pandas 数据框一起使用(这两个包中的键控方法可疑地相似)。非常感谢任何对此的帮助。

【问题讨论】:

到底是什么问题? testdata$block0_values 不会返回您从 panda 中保存的值吗? 问题是能够在熊猫中再次重新打开(请参阅我问题的后半部分)。我可以转换为 R data.frame(或 data.table)做一些操作,但我不能轻易保存回 pandas(没有另一个,可能更复杂的包装器)。 我认为您要问的内容非常有用。现在,使用这样的东西是否可以接受:pandas.pydata.org/pandas-docs/stable/r_interface.html 或者甚至在最近的 ipython 中使用 R 桥支持? (ipython.org/ipython-doc/stable/config/extensions/rmagic.html) 【参考方案1】:

如何在 HDF5 中编写数据帧以便可以在 R 中读取现在位于 Pandas 文档中: http://pandas-docs.github.io/pandas-docs-travis/io.html#external-compatibility

【讨论】:

是的,我已经在我对第一个答案的评论中链接了那里。遗憾的是,在我自己的个人测试中它不是一个非常有效的库(与 data.table 的 fread 相比),但也许我应该再试一次。感谢您的关注。【参考方案2】:

我推荐使用feather,由 Wes 和 Hadley 构建,以解决 R 和 Python 之间高效传输数据的问题。

Python

import numpy as np
import pandas as pd
import feather as ft

df = pd.DataFrame('N': np.random.randn(5))
ft.write_dataframe(df, 'df.feather')

R

library(data.table)
library(feather)

dt <- data.table(read_feather("df.feather"))
dt
           N
1: 0.2777700
2: 1.4083377
3: 1.2940691
4: 0.8221348
5: 1.8552908

【讨论】:

好建议!它不是 hdf5,但可以说解决了我想要的基本工作流程。嗯...需要决定是否接受这个答案,因为它没有直接回答所述问题,而是更深入地提出了一种解决我希望的一般工作流程的方法。【参考方案3】:

如果您仍在查看此内容,请查看 Google 群组上的此帖子。它展示了如何通过 HDF5 在 pandas/R 之间交换数据。

https://groups.google.com/forum/?fromgroups#!topic/pydata/0LR72GN9p6w

【讨论】:

太棒了,我第一次读到这篇文章时,我认为它不会去任何地方,但我又遇到了这个,看起来已经取得了进展,特别是因为它现在在文档中: pandas.pydata.org/pandas-docs/stable/…。如果它有效,将测试并给你信用;) 遗憾的是我无法让它工作,而且 R 的 hdf5 加载似乎需要很长时间。我现在在 data.table 中使用新的 fread 函数:r.789695.n4.nabble.com/…【参考方案4】:

下拉到 pytables 并在那里存储/获取您的数据是有意义的。

最终,DataFrame 是 Series 的字典,这就是 HDF5 表。由于不兼容的 dtypes,翻译存在限制,但对于数字数据,它应该是直截了当的。

pandas 存储 HDF5 的方式更像是二进制 blob。它必须支持 HDF5 完全支持的 DataFrame 的所有细微差别。

https://github.com/dalejung/trtools/blob/master/trtools/io/pytables.py

有一些类似 pandas/hdf5 的修改代码。

【讨论】:

所以你推荐在pandas和R之间的pytables中写一个自定义的兼容层?我想我需要弄清楚哪个具有更简单的 HDF5 格式(R 或 pandas)并将其作为我的基本数据类型,然后在我读写时在任一端提供一个转换器。 是的。您可以想象编写一个 R 适配器来在语义上读/写 pandas hdf。但是创建语义 HDF 并在两端都有简单的包装器似乎更容易。【参考方案5】:

您可以使用csv 文件作为通用数据格式。 R 和 python pandas 都可以轻松使用它。您可能会失去一些精度,但如果这是一个问题取决于您的具体问题。

【讨论】:

当然可以,但这意味着我会失去 hdf5 格式的速度和便利性。 R 在解析大文本文件时非常慢(这就是为什么我经常在 R 中使用 STATA 的 dta 格式来处理大数据)。我宁愿不在 python 中编写代码来写入 dta(在 statsmodels 包中有一个可用的阅读器)。 具有讽刺意味的是,这就是我现在所做的,因为 data.table 对 csv 的超快速 fread 功能。很抱歉之前的投票失败。 @GriffithRees 您可以将我的答案标记为正确的答案以弥补投反对票;) @Paul 但是,您的答案不正确。 CSV 根本不是一个实用的解决方案,在架构上也不是一个好的解决方案,也不是一个创造性的解决方案。 @GriffithRees,似乎仍然没有进展,我一直被这个问题困扰着。我已经开始研究我自己的专用二进制数据格式,用于与 R、Python 的 Pandas、C#/F# 的 Deedle 和 Scala 的 Saddle 兼容的数据帧。如果我完成我的项目,我会发布一个链接。

以上是关于如何在 hdf5 中有效地保存 python pandas 数据帧并将其作为 R 中的数据帧打开?的主要内容,如果未能解决你的问题,请参考以下文章

大 HDF5 数据集,如何在每个 epoch 后有效地洗牌

基于HDF5的高维数据有效

如何压缩保存在 hdf5 中的数据?

将 HDF5 文件转换为其他格式

保存到 hdf5 非常慢(Python 冻结)

用于python和R之间数据交换的HDF5