2

rpy2 は、いくつかの異なる方法で R コードを評価できます。

方法 A - 文字列を R コードとして評価する

import rpy2.robjects as rob
rcode = '''
print(summary(mtcars))
'''
rob.r(rcode)

方法 B - Python オブジェクトを使用して R コードを評価する

import rpy2.robjects as rob
rsummary = rob.r['summary']
mtcars = rob.r('mtcars')
print rsummary(mtcars)

rpy2のドキュメントでは、「大きなオブジェクトでこれを行うと、計算能力を最大限に活用できない可能性がある」ため、方法 A に対して警告されています。なぜでしょうか? 既知のベンチマークはありますか?

私が方法 A を好むのは、従うのが簡単で、2 つの言語を分離したままにし、既存の R コード スニペットに詰め込むことができるからです。しかし、その道を行くことで何を犠牲にするのか、もっと知りたいです。これについての洞察は大歓迎です。

4

1 に答える 1

2

これはすべてデータの処理に帰着します.Pythonにデータがない場合は、必ず方法Aを使用してください.

メソッド A は、サブプロセスを使用して R を実行するのとほとんど同じです。Python を使用してファイル script.R を作成し、そのスクリプトを実行することを想像してみてください。これは、大量のデータを処理し始めるまで問題なく動作します。

次に例を示します。

from rpy2 import robjects as ro
import numpy
data = numpy.random.random(1000)

これで、Python で 1000 個の要素を持つベクトルを取得できました。R で何かを行う場合は、変換する必要があります。メソッド A は次のようになります。

vecstr = "c({})".format(",".join(map(str, data)))
cmd = 'hist({},xlab="val", ylab="count", main="")'.format(vecstr)
ro.r(cmd)

どこでlen(cmd)>15000。すべてをファイルに書き込み、R スクリプトを個別に呼び出す方がよいでしょう (subprocessing上記のように、python のモジュールを使用)。または、方法 B のようにこれを行うこともできます。

ro.r.hist(ro.FloatVector(data), xlab="val", ylab="count", main="")

これははるかにクリーンで、ベクトルの長さが 1000 ではなく 100 万の場合でも問題はありません。

効率の問題について:

In [29]: data1 = numpy.random.random(1000)

In [30]: data2 = numpy.random.random(1000)

In [31]: %%timeit
   ....: ro.r.cor(ro.FloatVector(data1), ro.FloatVector(data2))[0]
   ....: 
1000 loops, best of 3: 1.01 ms per loop

In [32]: %%timeit
   ....: vec1str = "c({})".format(",".join(map(str, data1)))
   ....: vec2str = "c({})".format(",".join(map(str, data2)))
   ....: ro.r("cor({},{})".format(vec1str, vec2str))
   ....: 
100 loops, best of 3: 5.86 ms per loop

あまり多くを実行していない単純なおもちゃの例と、比較的小さなデータセットの場合、文字列に変換しない方が約 5 ~ 6 倍高速に見えます。

于 2013-11-12T23:53:00.113 に答える