2012-02-29 4 views
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와 함께 사용

데이터를 numpy 배열로 읽고 rpy2 함수를 사용해야합니다. 그러나 배열을 rpy2와 함께 사용하기 전에 누락 된 값을 마스크해야합니다.

나는 값을 마스킹하는 데 아무런 문제가 없지만 rpy2가 결과 마스크 된 배열로 작업 할 수 없습니다. 아마 numpy2ri 변환이 가면으로 배열 된 numpy 배열에서 작동하지 않는 것 같습니다. (아래 오류 참조)

어떻게하면됩니까? rpy2에 마스크 된 값을 무시하도록 지시 할 수 있습니까? 나중에 고급 통계를 수행 할 것이기 때문에 scipy/numpy를 직접 사용하는 대신 R을 사용하고 싶습니다.

감사합니다.

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와 배열을 처리 할 수 ​​없기 때문에, 나는 NaN의 값을 NumPy와 내 -99 값을 변환했습니다. 분명히 rpy2는 R 스타일 NA 값으로 numpy NaN 값을 인식합니다.

다음 코드는 r.sd() 호출에서 rpy2에 NA 값을 사용하지 않도록 알릴 수 있기 때문에 작동합니다. 그러나 초기 NaN 대체는 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 

답변

2

"마스크 값"(즉, 마스킹 될 지수 목록에 결합 값의 어레이이다)의 개념은 직접로 설정되는 R 값의 R.

에없는 "누락"(NA) 또는 원본 데이터 구조의 하위 집합이 취해 지므로 (이 하위 집합 만 포함하는 새 객체가 만들어집니다).

numpy에서 rinterface까지 rpy2에서 장면 뒤에 어떤 일이 일어나고있는 것은 numpy 배열을 R 배열로 복사한다는 것입니다 (다른 방법은 R 배열을 numpy로 노출 시키며 반드시 복사 할 필요는 없음) . 마스크가 그 단계에서 처리되지 않을 이유는 없습니다 (누군가가 패치를 제공하면 코드베이스에 더 빨리 영향을 미칠 수 있습니다). 대안은 마스크 값없이 numpy 배열을 생성 한 다음 이것을 rpy2에 제공하는 것입니다.

+0

numpy 배열에서 -99 값을 제거하는 문제는 배열 구조를 유지해야한다는 것입니다. 나는 rpy2가 가면으로 배열 된 numpy 배열로 작동하지 않는다는 것에 놀랐다. 아마도 사람들이 자주해야 할 필요가없는 것일까? 어쨌든, 귀하의 회신에 감사드립니다. – vulture

+0

rpy2 개발자라는 것을 깨닫지 못했습니다. Google에 제공해 주셔서 감사합니다. 나는 패치를 제공 할 수 있었으면 좋겠다.위의 코드를 해결 방법으로 업데이트했습니다. 지금 당장 생각해 볼 수 있습니다. – vulture

+0

그건 rpy2에만 국한된 것이 아닙니다. R은 마스크 된 배열을 가지고 있지 않으며, 동일한 개념은 "마스크 된 값"을 "누락"(R 영역의 NA)으로 설정하는 것입니다. – lgautier

1

당신은 기본적으로 numpy.ma에 정의 된 마스크 배열, 객체를 사용하여 NaN이 에 의해 -99 값을 대체하는 과정을 빠르게 할 수있는 다음 코드에서와 같이

:

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 배열)입니다.

관련 문제