1
import numpy
import rpy2
from rpy2 import robjects
import rpy2.robjects.numpy2ri

r = robjects.r
rpy2.robjects.numpy2ri.activate()

x = numpy.array( [1, 5, -99, 4, 5, 3, 7, -99, 6] )
mx = numpy.ma.masked_values( x, -99 )

print x         # works, displays all values
print r.sd(x)   # works, but uses -99 values in calculation

print mx        # works, now -99 values are masked (--)
print r.sd(mx)  # does not work - error

我是 rpy2 和 numpy 的新用户。我在 RHEL5 上使用 R 2.14.1、python 2.7.1、rpy2 2.2.5、numpy 1.5.1。

我需要将数据读入一个 numpy 数组并在其上使用 rpy2 函数。但是,在将数组与 rpy2 一起使用之前,我需要屏蔽缺失值。

我对屏蔽值没有问题,但我无法让 rpy2 处理生成的屏蔽数组。看起来 numpy2ri 转换可能不适用于屏蔽的 numpy 数组?(见下面的错误)

我怎样才能使这项工作?是否可以告诉 rpy2 忽略掩码值?我想坚持使用 R 而不是直接使用 scipy/numpy,因为我稍后会做更高级的统计。

谢谢。

Traceback (most recent call last):
  File "d.py", line 16, in <module>
    print r.sd(mx)  # does not work - error
  File "/dev/py/lib/python2.7/site-packages/rpy2-2.2.5dev_20120227-py2.7-linux-x86_64.egg/rpy2/robjects/functions.py", line 82, in __call__
    return super(SignatureTranslatedFunction, self).__call__(*args, **kwargs)
  File "/dev/py/lib/python2.7/site-packages/rpy2-2.2.5dev_20120227-py2.7-linux-x86_64.egg/rpy2/robjects/functions.py", line 30, in __call__
    new_args = [conversion.py2ri(a) for a in args]
  File "/dev/py/lib/python2.7/site-packages/rpy2-2.2.5dev_20120227-py2.7-linux-x86_64.egg/rpy2/robjects/numpy2ri.py", line 36, in numpy2ri
    vec = SexpVector(o.ravel("F"), _kinds[o.dtype.kind])
TypeError: ravel() takes exactly 1 argument (2 given)

更新:由于 rpy2 无法处理屏蔽的 numpy 数组,我尝试将我的 -99 值转换为 numpy NaN 值。显然 rpy2 将 numpy NaN 值识别为 R 风格的 NA 值。

下面的代码有效,因为在 r.sd() 调用中我可以告诉 rpy2 不要使用 NA 值。但是最初的 NaN 替换肯定比应用 numpy 掩码要慢。

你们中的任何一个 python 向导都可以给我一种更快的方法来跨大型 numpy ndarray 执行 -99 到 NaN 替换吗?或者也许建议另一种方法?

谢谢。

# 'x' is a large numpy ndarray I am working with
# ('x' in the original code above was a small test array)

for i in range(900, 950):           # random slice of numpy ndarray
  for j in range(6225):             # full extent across slice
    if x[i][j] == -99:
      x[i][j] = numpy.NaN

y = x[933]                          # random piece of converted range
sd = r.sd( y, **{'na.rm': 'TRUE'} ) # r.sd() call that ignores numpy NaN values
print sd
4

2 回答 2

2

“屏蔽值”的概念(即与要屏蔽的索引列表耦合的值数组)在 R 中并不直接存在。

在 R 中,值要么设置为“缺失”(NA),要么采用原始数据结构的子集(因此创建了仅包含该子集的新对象)。

现在在 numpy 到 rinterface 期间 rpy2 的幕后发生的事情是,将 numpy 数组复制到 R 数组中(反过来,将 R 数组暴露给 numpy,不一定需要复制)。在那个阶段没有理由不处理掩码(如果有人提供补丁,这可能会更快地进入代码库)。另一种方法是创建一个没有掩码值的 numpy 数组,然后将其提供给 rpy2。

于 2012-02-29T08:45:55.217 回答
1

您可以通过使用掩码数组(在 numpy.ma 中原生定义的对象)来加快将 -99 值替换为 NaN 的过程

如以下代码所示:

x_masked = numpy.ma.masked_array(x, mask= (x==-99) )
x_filled = x_masked.filled( numpy.NaN )

x_masked 是一个 numpy.ma(屏蔽数组)。x_filled 是一个 numpy.ndarray (常规 numpy 数组)

于 2013-04-10T14:25:23.997 回答