【问题标题】:Converting numpy to R array using rpy2 low level interface使用 rpy2 低级接口将 numpy 转换为 R 数组
【发布时间】:2018-01-03 16:39:07
【问题描述】:

关于SO的相关答案很多,但都是使用rpy2提供的高级robjects接口。但是,如果我想使用低级接口,我该怎么做呢?以下是一个 MCVE(前提是您在 R 中安装了 package copula):

备选方案 1,仅使用 the docs 中的低级接口

import numpy as np
from rpy2 import rinterface as ri

ri.initr()

def rimport(packname):
    as_environment = ri.baseenv['as.environment']
    require = ri.baseenv['require']
    require(ri.StrSexpVector([packname]),
            quiet = ri.BoolSexpVector((True, )))
    packname = ri.StrSexpVector(['package:' + str(packname)])
    pack_env = as_environment(packname)
    return pack_env

Copula = rimport('copula')

# The ri.SexpVector line causes the problem, but this is how the docs has it.
gc = Copula['gofCopula'](copula=Copula['gumbelCopula'](dim=5),
                         x=ri.SexpVector(np.random.randn(100,5), ri.REALSXP),
                         N=ri.IntSexpVector((1000,)),
                         simulation=ri.StrSexpVector(('mult',)))
死于:
RRuntimeError                             Traceback (most recent call last)
<ipython-input-3-63487c32d528> in <module>()
      2                          x=ri.SexpVector(np.random.randn(100,5), ri.REALSXP),
      3                          N=ri.IntSexpVector((1000,)),
----> 4                          simulation=ri.StrSexpVector(('mult',)))
      5 
      6 gc

RRuntimeError: Error: (d <- ncol(x)) > 1 is not TRUE

备选方案 2,使用 numpy2ri,如 SO 上的所有答案所示

import numpy as np
from rpy2 import rinterface as ri
from rpy2.robjects import numpy2ri

ri.initr()
numpy2ri.activate()

def rimport(packname):
    as_environment = ri.baseenv['as.environment']
    require = ri.baseenv['require']
    require(ri.StrSexpVector([packname]),
            quiet = ri.BoolSexpVector((True, )))
    packname = ri.StrSexpVector(['package:' + str(packname)])
    pack_env = as_environment(packname)
    return pack_env

Copula = rimport('copula')

# Automatic conversion does not happen!
gc = Copula['gofCopula'](copula=Copula['gumbelCopula'](dim=5),
                         x=np.random.randn(100,5), # Hoping for automatic conversion
                         N=ri.IntSexpVector((1000,)),
                         simulation=ri.StrSexpVector(('mult',)))
死于:
ValueError                                Traceback (most recent call last)
<ipython-input-1-17b2b5105f01> in <module>()
     24                          x=np.random.randn(100,5),
     25                          N=ri.IntSexpVector((1000,)),
---> 26                          simulation=ri.StrSexpVector(('mult',)))
     27 
     28 gc

ValueError: All parameters must be of type Sexp_Type,or Python int/long, float, bool, or None

替代方案 3,同时使用两者

像备选方案 1 一样死去。


补充说明

1)

list(ri.SexpVector(np.random.randn(100,5), ri.REALSXP))

是一个包含 NA_real_ 的列表,正好有 100 个。

2)

如果我放弃低级接口,只使用高级接口,一切正常。但这不是我想要的。

import numpy as np
from rpy2.robjects.packages import importr
from rpy2.robjects import numpy2ri

numpy2ri.activate()

Copula = importr('copula')
gc = Copula.gofCopula(copula=partial(Copula.gumbelCopula, dim=5)(),
                      x=np.random.randn(100,5),
                      N=1000,
                      simulation='mult')

【问题讨论】:

    标签: python numpy rpy2


    【解决方案1】:

    感谢您对高级界面和其中的工作的称赞,尽管这是一个隐含的:它确实是为“工作”而设计的。

    低级接口非常接近 R 的 C 级 API,它的使用可能需要更多关于它的知识,这对于 Python 用户来说是合理的期望。请注意,遗憾的是,发布的文档并不完整,因为未包含文档字符串 (issue with readthedocs)。

    我鼓励您使用高级界面,除非有特定原因不这样做,但由于源是开放的,因此可以轻松检查转换器中发生的事情(它是 here)。

    【讨论】:

    • 您好,伊戈捷!我希望你一直做得很好。在之前your answer 的讨论中,我们发现了高级接口和多处理的一些限制。我通常使用大型数据集,不幸的是,很多优秀的统计包在 Python 中没有对应的(copula 就是其中之一)。所以我必须使用 R。将 copula 模型拟合到我的数据的一个子集大约需要 14 个小时,其中我有 28 个。所以,并行是要走的路。因此,我希望使用与多处理一起使用的低级接口
    • 我真正的问题是,如何使用低级 rinterface 将 numpy 数组转换为 R 矩阵,同时保留数组的形状。尽管高级 api 很棒,而且我非常感谢制作它的所有伟大工作,但它并没有解决我的具体问题。感谢您指出源代码中numpy2ri 的确切位置。这对在我的脚本中进行复制非常有帮助。
    猜你喜欢
    • 2011-02-09
    • 2015-09-25
    • 2011-06-03
    • 2019-09-02
    • 2018-02-11
    • 2013-01-05
    • 2012-07-20
    • 2012-10-30
    • 2014-04-15
    相关资源
    最近更新 更多