如何在 Python 和 R 之间交换 Msgpack 文件?

Posted

技术标签:

【中文标题】如何在 Python 和 R 之间交换 Msgpack 文件?【英文标题】:How to exchange Msgpack files between Python and R? 【发布时间】:2019-08-29 21:28:56 【问题描述】:

考虑这个简单的例子

import pandas as pd

mydata = pd.DataFrame('mytime': [pd.to_datetime('2018-01-01 10:00:00.513'),
                                pd.to_datetime('2018-01-03 10:00:00.513')],
                      'myvariable': [1,2],
                      'mystring': ['hello', 'world'])
mydata
Out[7]: 
  mystring                  mytime  myvariable
0    hello 2018-01-01 10:00:00.513           1
1    world 2018-01-03 10:00:00.513           2

我知道我可以使用Pandas 将该数据帧写入msgpack

mydata.to_msgpack('C://Users/john/Documents/mypack')

问题是:如何读取R 中的msgpack 文件?

使用RcppMsgPack会返回一些不是dataframe/tibble的令人费解的输出

library(tidyverse)
library(RcppMsgPack)

df <- msgpack_read('C://Users/john/Documents/mypack', simplify = TRUE)
 > df
$axes
$axes[[1]]
$axes[[1]]$typ
[1] "index"

$axes[[1]]$name
NULL

$axes[[1]]$klass
[1] "Index"

$axes[[1]]$compress
NULL

$axes[[1]]$data
[1] "mystring"   "mytime"     "myvariable"

$axes[[1]]$dtype
[1] "object"


$axes[[2]]
$axes[[2]]$typ
[1] "range_index"

$axes[[2]]$name
NULL

$axes[[2]]$klass
[1] "RangeIndex"

$axes[[2]]$start
[1] 0

$axes[[2]]$step
[1] 1

$axes[[2]]$stop
[1] 2



$typ
[1] "block_manager"

$blocks
$blocks[[1]]
$blocks[[1]]$shape
[1] 1 2

$blocks[[1]]$klass
[1] "IntBlock"

$blocks[[1]]$compress
NULL

$blocks[[1]]$values
 [1] 01 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00
attr(,"EXT")
[1] 0

$blocks[[1]]$locs
$blocks[[1]]$locs$typ
[1] "ndarray"

$blocks[[1]]$locs$dtype
[1] "int64"

$blocks[[1]]$locs$compress
NULL

$blocks[[1]]$locs$ndim
[1] 1

$blocks[[1]]$locs$data
[1] 02 00 00 00 00 00 00 00
attr(,"EXT")
[1] 0

$blocks[[1]]$locs$shape
[1] 1


$blocks[[1]]$dtype
[1] "int64"


$blocks[[2]]
$blocks[[2]]$shape
[1] 1 2

$blocks[[2]]$klass
[1] "DatetimeBlock"

$blocks[[2]]$compress
NULL

$blocks[[2]]$values
 [1] 40 02 0e 64 4d a7 05 15 40 02 ac 86 76 44 06 15
attr(,"EXT")
[1] 0

$blocks[[2]]$locs
$blocks[[2]]$locs$typ
[1] "ndarray"

$blocks[[2]]$locs$dtype
[1] "int64"

$blocks[[2]]$locs$compress
NULL

$blocks[[2]]$locs$ndim
[1] 1

$blocks[[2]]$locs$data
[1] 01 00 00 00 00 00 00 00
attr(,"EXT")
[1] 0

$blocks[[2]]$locs$shape
[1] 1


$blocks[[2]]$dtype
[1] "datetime64[ns]"


$blocks[[3]]
$blocks[[3]]$shape
[1] 1 2

$blocks[[3]]$klass
[1] "ObjectBlock"

$blocks[[3]]$compress
NULL

$blocks[[3]]$values
[1] "hello" "world"

$blocks[[3]]$locs
$blocks[[3]]$locs$typ
[1] "ndarray"

$blocks[[3]]$locs$dtype
[1] "int64"

$blocks[[3]]$locs$compress
NULL

$blocks[[3]]$locs$ndim
[1] 1

$blocks[[3]]$locs$data
[1] 00 00 00 00 00 00 00 00
attr(,"EXT")
[1] 0

$blocks[[3]]$locs$shape
[1] 1


$blocks[[3]]$dtype
[1] "object"



$klass
[1] "DataFrame"

我该怎么办?

当然,从 R 回到 Python 也不错。谢谢!

【问题讨论】:

它的超长。让我看看我能不能做到 @Parfait 完成了我的男人\ 是的,看起来是 Pythonic 元素:dtype, ndarray....很好奇,相同的 R 数据如何与 msgpack 看?可以在 Pandas 中读取吗? @Parfait 这是一个有趣的观点。我不知道。但也许我们可以先从等式的那一边开始:) 显然,pandas DataFrame 的msgpack 表示级别非常低,因此它不能按原样转换为适合 R 的对象。您要么编写一些代码将RcppMsgPack 输出转换为R data.frame,要么更改生成msgpack 文件的过程。后一种解决方案当然要好得多:生成只能用特定语言读取的输出是一种非常糟糕的做法。 【参考方案1】:

你在 R 中使用 library(reticulate) 怎么样:

library(reticulate)
pyData = py_run_string("import pandas as pd
mydata = pd.DataFrame('mytime': [pd.to_datetime('2018-01-01 10:00:00.513'),
                                pd.to_datetime('2018-01-03 10:00:00.513')],
                      'myvariable': [1,2],
                      'mystring': ['hello', 'world'])")

它将产生所需的输出:

pyData$mydata
    mystring              mytime myvariable
1    hello 2018-01-01 10:00:00          1
2    world 2018-01-03 10:00:00          2

您可以将所有 python 代码保存在 python 文件中,例如mydata.py 并使用函数py_run_file("mydata.py")

可以在此处找到reticulate 的概述:https://github.com/rstudio/reticulate。

你最感兴趣的可能是类型转换的描述:

来源:https://github.com/rstudio/reticulate#type-conversions。

附加问题 - 从 R 到 Python:

类型转换也适用于从 R 到 Python 的“发送”数据,请参见此处:https://rstudio.github.io/reticulate/articles/calling_python.html#sourcing-scripts。

py = py_run_string("def add(x, y):
  return x + y")

py$add(5, 10)
15

【讨论】:

很有趣,但我需要一个纯 R 解决方案 这是一个纯 R 解决方案。它使用一个 R 包。是的,它与一种语言交互,但其他使用 RCpp (C++) 或 RJava 的 R 包也是如此! 不,不幸的是reticulate 不适用于我的网络设置(我无法让该软件包正常工作)。所以我正在寻找利用 R 中的 msgpack 包的东西。 另外,该解决方案根本没有解决msgpack Python/R 兼容性问题。 艰难!这绕过了从磁盘读取/写入的 I/O 需求。

以上是关于如何在 Python 和 R 之间交换 Msgpack 文件?的主要内容,如果未能解决你的问题,请参考以下文章

如何本机读取羽毛/箭头文件?

如何原生阅读羽毛文件?

R和Python之间的双向通信

通过套接字在 C++ 和 python 之间交换固定浮点数组

在 C/C++ 和 Python 之间交换值的应用程序设计

django/python - 在我的基础架构和客户之间交换数据的推荐安全方式是啥?