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
Проблема с удалением значений -99 из массива numpy заключается в том, что мне нужно сохранить структуру массива. Я удивлен, что rpy2 не может работать с масками в массивах numpy - может быть, это не то, что люди должны делать очень часто? В любом случае, спасибо за ваш ответ. – vulture
Не понял, что вы разработчик rpy2. Спасибо, что предоставили его нам! Мне жаль, что у меня не было возможности предоставить патч.Я обновил свой код выше с помощью обходного пути, на что я могу придумать. – vulture
Это не особая вещь, относящаяся к rpy2. R не имеет маскированных массивов, и эквивалентная концепция заключается в том, чтобы установить «маскированные значения» в «отсутствующие» (NA в мире R). – lgautier