Использование маскированных массивов с rpy2 - PullRequest
1 голос
/ 29 февраля 2012
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.Однако мне нужно замаскировать пропущенные значения перед использованием массива с 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 не может обрабатывать маскированные массивы, я попытался преобразовать мои значения -99 в значения NaN.Очевидно, что rpy2 распознает пустые значения NaN как значения NA в стиле R.

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

Может ли кто-нибудь из вас, Python-волшебник, дать мне более быстрый способ замены от -99 до NaN на большом Numpy 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 ]

2 голосов
/ 29 февраля 2012

Понятие "замаскированных значений" (то есть массива значений, связанных со списком маскируемых индексов) не существует непосредственно в R.

В значениях R либо установлены, чтобы быть "пропущено "(NA), или взято подмножество исходной структуры данных (поэтому создается новый объект, содержащий только это подмножество).

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

1 голос
/ 10 апреля 2013

Вы можете ускорить процесс замены -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)

...