MATLAB эквивалентно NumPy замаскированным массивам? - PullRequest
1 голос
/ 04 мая 2020

Желаемое поведение

В Python я могу создать замаскированный массив в NumPy примерно так:

>>> import numpy as np
>>> x = np.arange(1, 7).reshape(3, 2)
>>> x = np.ma.array(x, mask=[[0, 0], [1, 0], [0, 0]])
>>> x
masked_array(
  data=[[1, 2],
        [--, 4],
        [5, 6]],
  mask=[[False, False],
        [ True, False],
        [False, False]],
  fill_value=999999)

И затем вычисления обрабатывают его так, как если бы маскированные значения не существовать. Например, сравните

# Matrix multiplication on raw data.

>>> np.dot(x.data, x.data.T)
array([[ 5, 11, 17],
       [11, 25, 39],
       [17, 39, 61]])

# Matrix multiplication on masked data.

>>> np.ma.dot(x, x.T)
masked_array(
  data=[[5, 8, 17],
        [8, 16, 24],
        [17, 24, 61]],
  mask=[[False, False, False],
        [False, False, False],
        [False, False, False]],
  fill_value=999999)

Обратите внимание, что это отличается от заполнения маскированных значений нулем или наном, поскольку такие вещи, как деление на ноль, игнорируются. Например:

>>> y = np.copy(x.data)
>>> y
array([[1, 2],
       [3, 4],
       [5, 6]])

>>> y / x
masked_array(
  data=[[1.0, 1.0],
        [--, 1.0],
        [1.0, 1.0]],
  mask=[[False, False],
        [ True, False],
        [False, False]],
  fill_value=999999)

>>> z = np.copy(x.data)
>>> z[1, 0] = 0
>>> z
array([[1, 2],
       [0, 4],
       [5, 6]])

>>> y / z
...RuntimeWarning: divide by zero encountered in true_divide...
array([[ 1.,  1.],
       [inf,  1.],
       [ 1.,  1.]])

Вопрос

Мой вопрос: есть ли способ воспроизвести эту функцию в MATLAB? Я пробовал nan, но я получаю ошибки в последующих функциях вызываемого абонента, например, minFun c.

1 Ответ

0 голосов
/ 05 мая 2020

Вы можете использовать логики , чтобы сделать это. Создайте матрицу логики того же размера, что и матрицу, которую вы хотите проверить, и используйте ее для индексации. Если вы хотите придерживаться NaN, вы можете использовать isnan(), чтобы создать логическую матрицу того же размера и сделать, как описано выше. Или некоторые фундаментальные функции имеют возможность установить флаг 'omitNaN', например. mean.

A = rand(5,3);
% create logical matrix
lg = A > 0.5;
% index matrix
A(lg) = NaN % still a 5x3 matrix
A(~lg) % this is (most likely) a vector now! because MATLAB does not know how to handle rows with different number of elements
mean(A)
mean(A,'omitNaN')
mean(A(~lg))


Вывод:

>> A(lg) = NaN
 A =

       NaN    0.0975    0.1576
       NaN    0.2785       NaN
    0.1270       NaN       NaN
       NaN       NaN    0.4854
       NaN       NaN       NaN

>>A(~lg)

ans =

    0.1270
    0.0975
    0.2785
    0.1576
    0.4854

>> mean(A)

ans =

   NaN   NaN   NaN

>> mean(A,'omitNaN')

ans =

    0.1270    0.1880    0.3215

>> mean(A(~lg))

ans =

    0.2292

Обсуждение: Обратите внимание, что это не ясно как упорядочить оставшиеся элементы матрицы, если вырезать все элементы вектора логического индекса lg из матрицы A. Поэтому MATLAB сворачивает матрицу в вектор (интересно, что это вектор, а не массив ...). Однако, если вы назначите NaN s элементам, которые вы хотите вырезать, форма будет сохранена. Это разрушает любую функцию, которая использует все элементы строки / столбца, если она не может обработать NaN s (например, max не затрагивается). Так что mean(A) должен потерпеть неудачу - если вы не скажете ему игнорировать NaN с mean(A,'omitNaN'). Затем он усредняет когда-либо столбец (в направлении по умолчанию). Очевидно, что это не тот же результат, что и среднее значение всех числовых c элементов, которые не являются NaN: mean(A(~lg)).

Кстати, это тот же результат, как если бы вы сказали среднему значению: усредните все элементы матрицы, которые не являются NaN: mean(A,'all','omitNaN') (обратите внимание, что порядок флагов здесь важен!)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...