我正在使用rpy2包为python带来一些R功能。 我在R中使用的函数需要一个data.frame对象,通过使用rlike.TaggedList然后使用robjects.DataFrame我可以使这个工作。
然而,我遇到了性能问题,与具有完全相同数据的完全相同的R函数相比,这使我尝试使用这里提到的rpy2低级接口 - http://rpy.sourceforge.net/rpy2/doc-2.3/html/performances.html
到目前为止,我已经尝试过:
使用如下字典转储TaggedList和DataFrame类:
d = dict((var_name, var_sexp_vector) for ...)
dataframe = robjects.r('data.frame')(**d)
两者都没有给我任何明显的加速。
我注意到DataFrame对象可以在它们的构造函数中得到一个rinterface.SexpVector,所以我想到创建一个这样的命名向量,但我不知道如何输入名称(在RI中知道它的名字(vec)= c('a','b'......))。
我该怎么做?还有另外一种方法吗? 有没有一种简单的方法来描述rpy本身,所以我可以知道瓶颈在哪里?
修改
以下代码似乎在较新的rpy(2.2.3)
上运行良好(x4更快)data = ro.r('list')([ri.FloatSexpVector(x) for x in vectors])[0]
data.names = ri.StrSexpVector(vector_names)
然而它不适用于版本2.0.8(最后一个受Windows支持),因为R似乎无法使用名称:“eval中的错误(expr,envir,enclos):对象'y'不是发现“
想法?
编辑#2: 有人为windows(python 2.7)构建rpy2.3二进制文件做得很好,所提到的工作很棒(对于我的代码几乎快了x6)
link:https://bitbucket.org/breisfeld/rpy2_w32_fix/issue/1/binary-installer-for-win32
答案 0 :(得分:1)
Python可以比R快几倍(甚至是字节编译的R),我设法在R数据结构上执行操作,其中rpy2比R更快。共享相关的R和rpy2代码将有助于提出更具体的建议(如果需要,还可以改进rpy2)。
与此同时,SexpVector可能不是你想要的;它只不过是所有R向量的抽象类(参见class diagram for rpy2.rinterface)。 ListSexpVector
可能更合适:
import rpy2.rinterface as ri
ri.initr()
l = ri.ListSexpVector([ri.IntSexpVector((1,2,3)),
ri.StrSexpVector(("a","b","c")),])
一个重要的细节是R列表是递归数据结构,并且R通过使运算符“[[”(除了“[”)来避免捕获22类型的情况。 Python没有那个,我还没有(但是)在低级别实现“[[”作为一种方法。
例如,可以使用模块stdlib模块cProfile完成Python中的分析。