使用 rpy2 低级接口将 numpy 转换为 R 数组
Converting numpy to R array using rpy2 low level interface
SO上有很多相关的回答,但是都是用R中安装的rpy2
. But, if I wanted to use the low-level interface, how do I go about it? Following is a MCVE (provided you have the package copula
提供的高级robjects
接口:
备选方案 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')
感谢您对高级界面及其相关工作的称赞,虽然这是一个隐含的界面:它确实旨在 "just work"。
低级接口与 R 的 C 级接口非常接近 API,它的使用可能需要更多关于它的知识,这被认为是 Python 观众的合理期望。请注意,很遗憾,发布的文档并不完整,因为未包含文档字符串 (issue with readthedocs)。
除非有特殊原因,否则我鼓励您使用高级界面,但由于源代码是开放的,因此可以轻松检查转换器中发生的事情(here)。
SO上有很多相关的回答,但是都是用R中安装的rpy2
. But, if I wanted to use the low-level interface, how do I go about it? Following is a MCVE (provided you have the package copula
提供的高级robjects
接口:
备选方案 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')
感谢您对高级界面及其相关工作的称赞,虽然这是一个隐含的界面:它确实旨在 "just work"。
低级接口与 R 的 C 级接口非常接近 API,它的使用可能需要更多关于它的知识,这被认为是 Python 观众的合理期望。请注意,很遗憾,发布的文档并不完整,因为未包含文档字符串 (issue with readthedocs)。
除非有特殊原因,否则我鼓励您使用高级界面,但由于源代码是开放的,因此可以轻松检查转换器中发生的事情(here)。