Линейная индексация, логическая индексация и все такое

мы привыкли к различным формам индексирования в Matlab:

  • standard (используя целые числа вдоль каждого измерения),
  • логический (с помощью логических значений),
  • linear (использование одного индекса для пересечения массива с более чем одним измерением).

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

>> A = magic(3)
A =
     8     1     6
     3     5     7
     4     9     2
>> A(A>5)
ans =
     8
     9
     6
     7

это логическое индексирование, верно? Но он также имеет некоторые особенности линейной индексации, потому что вектор-столбец возвращается. На самом деле, логический индекс A>5 имеет тот же эффект, что линейный индекс find(A>5).

во втором примере рассмотрим

>> A = magic(3)
A =
     8     1     6
     3     5     7
     4     9     2
>> A(1:2, [true false true])
ans =
     8     6
     3     7

в этом выражении для первой координаты используется стандартное (целочисленное) индексирование,а для второй-логическое.

эти примеры (и более сложные, которые возникают на практике) задают следующие вопросы:

  • какие типы индексирования существуют в Matlab?
  • как их можно комбинировать?
  • как их следует называть?

1 ответов


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

этот ответ пытается прояснить различные типы индексации и то, как они могут быть объединены. Другой вопрос, как формы (size) выходных массив определяется как функция от формы индексных переменных. Хороший пост на этом сущность индексации Лорен Шур.

описание следовать фокусируется на индексации числовые массивы, но его можно применить к ячейки массивов с индексированием скобок или фигурных скобок, с очевидным изменением типа вывода (массив ячеек или список, разделенный запятыми, соответственно). Это будет кратко обсуждаться на конец.

типы индексации в числовых массивах

индексирование можно классифицировать с учетом следующих двух атрибутов.

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

    • чисто многомерная индексирование задает переменную индекса для каждого измерения массива. Отдельные индексы иногда называют подстрочные в документации Matlab (см., например,sub2ind).
    • чисто линейный индексирование указывает одну переменную индекса, которая пересекает массив по всем измерениям (это можно рассматривать, как если бы все измерения свернулись в одно). Как мы знаем, обход сначала вдоль столбцов, затем вдоль строк, затем вдоль третий-тусклые ломтики и т. д. (Так называемые колонка-главный заказ).
    • частично линейный индексирование: учитывая массив с m+n размеры n>=2, можно указать m переменные индекса для первого m измерения (таким образом, используя многомерную индексацию в этих измерениях) и одну переменную индекса для последнего n dimensions, который интерпретируется как линейный индекс только для этих измерений (последний n размеры рухнуть в один.)
  2. согласно типу значений индекса, каждая переменная индекса может быть целочисленной или логической:

    • это целочисленное если переменная index содержит положительные целые числа;
    • это логическое если переменная index содержит логические значения.

критерии классификации 1 и 2 независимая. Категория индекс с точки зрения критерия 1 не имеет отношения к своей категории согласно критерию 2. Возможны все комбинации.

таким образом, согласно вышеуказанной классификации, есть 6 основные типы индексации. Чтобы уточнить, ниже приведен пример для каждого. Во всех примерах используется массив A = cat(3, magic(3), 9+magic(3)), то есть

A(:,:,1) =
     8     1     6
     3     5     7
     4     9     2
A(:,:,2) =
    17    10    15
    12    14    16
    13    18    11
  1. многомерные, целочисленные значения:

    >> A([1 2], 2, 2)
    ans =
        10
        14
    
  2. линейный, целочисленное значение:

    >> A([2 5:7])
    ans =
         3     5     9     6
    
  3. частично линейное, целочисленное:

    >> A([1 2], 2:4)
    ans =
         1     6    17
         5     7    12
    
  4. многомерный, логичный:

    >> A([true true false], [false true false], [false true])
    ans =
        10
        14
    

    интересно, что количество логических значений может быть меньше или даже больше, чем размер в измерении, на которое ссылается индекс:

    >> A([true true], [false true false false], [false true])
    ans =
        10
        14
    

    пропущенные значения интерпретируются как false, а прибавочная стоимость должна быть false или произойдет ошибка. См., например,этот страница по Mathworks или этот ответ Джонас.

  5. линейные, логические:

    >> A([false true false false true true true])
    ans =
         3     5     9     6
    

    (обратите внимание, что 11 trailing false значения были опущены в векторе индексирования.)

  6. частично линейный, логический:

    >> A([true true false], [false true true true false false])
    ans =
         1     6    17
         5     7    12
    

в многомерной или частично линейной индексации, в которой существует более одной переменной индекса, каждая может быть независимо целочисленной или логический. Это приводит к различным смешанного типа. Например:

  1. многомерные, логические / целочисленные значения:

    >> A([true false true], [false true true], 2)
    ans =
        10    15
        18    11
    
  2. частично линейный, целочисленный/логический:

    >> A([1 2], [true false true false true false])
    ans =
         8     6    10
         3     7    14
    

если индексируемый массив является разреженные матрицы все вышеперечисленное по-прежнему применяется, за исключением того, что частично линейная индексация не существует для матриц; и, конечно, результат тоже редко.

индексация массивов ячеек

все типы индексирования, описанные для числовых массивов могут быть применены к ячейке массива, с одним дополнительным фактором. Массивы ячеек можно индексировать скобками или фигурными скобками. В первом случае результатом индексирования является массив ячеек. Во втором-список содержимого ячейки, разделенный запятыми.

в качестве примера предположим, что числовой массив, используемый в предыдущих примерах, преобразуется в массив ячеек C = num2cell(A), то есть

C(:,:,1) = 
    [8]    [1]    [6]
    [3]    [5]    [7]
    [4]    [9]    [2]
C(:,:,2) = 
    [17]    [10]    [15]
    [12]    [14]    [16]
    [13]    [18]    [11]

тогда индексирование, используемое в примере 8 выше, даст массив ячеек

>> C([1 2], [true false true false true false])
ans = 
    [8]    [6]    [10]
    [3]    [7]    [14]

в то время как использование фигурных скобок даст список, разделенный запятыми

>> C{[1 2], [true false true false true false]}
ans =
     8
ans =
     3
ans =
     6
ans =
     7
ans =
    10
ans =
    14 

сообщение на вынос / TL; DR

логическое и линейное индексирование не являются исключительными типами индексирования. Скорее, это две независимые особенности индексации. "Логический" относится к типу значений индекса, а " линейный" указывает, что несколько измерений сворачиваются и индексируются как одно. Обе функции могут происходить одновременно.