如何分区保存R函数的pyspark RDD

时间:2016-01-08 04:52:57

标签: python r apache-spark pyspark rpy2

describe SomeClass do
  describe '#test_method' do
    expect(SomeClass).to receive(:loop).and_yield
    expect(SomeClass).to receive(:make_heavy_lifting)
    expect(SomeClass).to receive(:sleep).with(60*60)
end

输出

import rpy2.robjects as robjects

dffunc = sc.parallelize([(0,robjects.r.rnorm),(1,robjects.r.runif)])
dffunc.collect() 

虽然分区版本会导致错误:

[(0, <rpy2.rinterface.SexpClosure - Python:0x7f2ecfc28618 / R:0x26abd18>), (1, <rpy2.rinterface.SexpClosure - Python:0x7f2ecfc283d8 / R:0x26aad28>)]
dffuncpart = dffunc.partitionBy(2)
dffuncpart.collect()

似乎这个错误是RuntimeError: ('R cannot evaluate code before being initialized.', <built-in function unserialize> 没有加载到其中一个分区上,我假设这意味着没有执行第一个导入步骤。有没有办法解决?

编辑1 第二个例子让我觉得pyspark或rpy2的时间存在错误。

R

产生相同的错误R在初始化之前无法评估代码。

dffunc = sc.parallelize([(0,robjects.r.rnorm),     (1,robjects.r.runif)]).partitionBy(2)
def loadmodel(model):
    import rpy2.robjects as robjects
    return model[1](2)
dffunc.map(loadmodel).collect()

按预期工作。

1 个答案:

答案 0 :(得分:2)

我想说&#34;这不是rpy2中的错误,这是一个功能&#34;但我实际上必须和#34结算;这是一个限制&#34;。

发生的事情是rpy2有2 interface levels。一个是低级别的(更接近R的C API)并且可以通过rpy2.rinterface获得,另一个是具有更多铃声和口哨声的高级界面,更多&#34; pythonic&#34 ;以及继承自rinterface level-one的R对象的类(最后一部分对于下面关于酸洗的部分很重要)。如果需要,导入高级接口会导致使用默认参数初始化(启动)嵌入式R.导入低级接口rinterface没有这种副作用,并且必须显式执行嵌入式R的初始化(函数initr)。 rpy2是这样设计的,因为嵌入式R的初始化可以有参数:先导入rpy2.rinterface,设置初始化,然后导入rpy2.robjects使这成为可能。

除此之外,rpy2包装的R对象的序列化(酸洗)目前仅在rinterface级别定义(参见documentation)。 Pickling robjects - 级别(高级别)rpy2对象正在使用rinterface级代码,当取消它们时,它们将保留在较低级别(Python pickle包含模块对象的类)定义并将导入该模块 - 这里rinterface,这并不意味着嵌入式R的初始化。事情就是这样的原因很简单,它现在已经足够好了#34;在实施这个时,我不得不同时想到一种很好的方法来桥接两种不同的语言,并通过我的方式学习Python C-API和pickle / unpickling Python对象。考虑到人们可以轻松编写类似

的内容
import rpy2.robjects

import rpy2.rinterface
rpy2.rinterface.initr()
在拆开之前,它从未被重新访问过。我所知道的rpy2酸洗的用法是使用Python的multiprocessing(并且在初始化子进程的代码中添加类似于import语句的东西是一种廉价且充分的修复)。愿这是再次审视这个问题的时候了。如果是这样,请提交rpy2的错误报告。

编辑这无疑是rpy2的一个问题。腌制的robjects级对象应该取消回到robjects - 级别,而不是rinterface级别。我打开了一个issue in the rpy2 tracker(并且已经在默认的/ dev分支中推送了一个基​​本的补丁)。

第二次编辑:该修补程序是从版本2.7.7开始发布的rpy2的一部分(撰写本文时的最新版本是2.7.8)。