2012-02-29 2 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. Я использую R 2.14.1, python 2.7.1, rpy2 2.2.5, numpy 1.5.1 на RHEL5.Использование маскированных массивов numpy с rpy2

Мне нужно прочитать данные в массив 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) 

Update: Поскольку rpy2 не может обрабатывать замаскированные Numpy массивов, я попытался преобразовать мои -99 значения Numpy значения NaN. По-видимому, rpy2 распознает numpy NaN-значения как значения NA в стиле R.

Код ниже работает, потому что в вызове r.sd() я могу указать rpy2 не использовать значения NA. Но начальная замена NaN определенно медленнее, чем применение маски numpy.

Может ли кто-нибудь из вас мастеров python дать мне более быстрый способ сделать замену -99 на NaN на большое число ndarray? Или, может быть, предложить другой подход?

Спасибо.

# '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) или подмножество исходной структуры данных (поэтому создается новый объект, содержащий только это подмножество).

Теперь, что происходит за сценой в rpy2 во время numpy to rinterface, заключается в том, что делается копия массива numpy в массив R (наоборот, выставляя массив R на numpy, необязательно требует копирования) , Нет никакой причины, по которой маски не будут обрабатываться на этом этапе (это может сделать путь к базе кода быстрее, если кто-то предоставляет патч). Альтернативой является создание массива numpy без замаскированных значений, затем подайте это на rpy2.

+0

Проблема с удалением значений -99 из массива numpy заключается в том, что мне нужно сохранить структуру массива. Я удивлен, что rpy2 не может работать с масками в массивах numpy - может быть, это не то, что люди должны делать очень часто? В любом случае, спасибо за ваш ответ. – vulture

+0

Не понял, что вы разработчик rpy2. Спасибо, что предоставили его нам! Мне жаль, что у меня не было возможности предоставить патч.Я обновил свой код выше с помощью обходного пути, на что я могу придумать. – vulture

+0

Это не особая вещь, относящаяся к rpy2. R не имеет маскированных массивов, и эквивалентная концепция заключается в том, чтобы установить «маскированные значения» в «отсутствующие» (NA в мире R). – lgautier

1

Вы можете ускорить процесс замены -99 значений на NaN с помощью замаскированных массивов, объектов, которые изначально определенных в numpy.ma

как показан в следующем коде:

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)

Смежные вопросы