Логическое индексирование символов в массиве гетерогенных ячеек в MATLAB


У меня есть гетерогенный массив ячеек, содержащий в основном числа, но один столбец символов. Я хотел бы определить те строки, в которых значение в столбце символов равно определенной строке, 'X'. Мой массив выглядит примерно так:

array_name = { [0] [2] 'X' ; 
               [4] [1] 'X' ; 
               [9] [7] 'A' ; 
               [9] [1] 'X' ; 
               [4] [4] 'B'};

Мой вопрос двоякий:

(1) поскольку использование array_name == 'X' не возвращает логический вектор, который я ожидал бы при использовании его на числовом массиве, как это сделать?

(2) Как я могу создать новый массив, состоящий только из те строки, которые удовлетворяют условию, что значение в символьном столбце равно 'X', так что мой вывод будет выглядеть следующим образом:

new_array = { [0] [2] 'X' ; 
              [4] [1] 'X' ; 
              [9] [1] 'X'};
Я заинтересован в (1) лишь постольку, поскольку предполагаю, что это будет необходимо для (2).

Любые намеки очень ценятся!

3 2

3 ответа:

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

L=[array_name{:,3}]=='X'
new_array=array_name(L,:)
В качестве альтернативы вы можете использовать strcmpi, который может работать с несколькими символами.
L=strcmpi(array_name(:,3),'X')
new_array=array_name(L,:)

Я не совсем понимаю ваш 1-й вопрос, Извините, но вот ответ на 2-й, который, я думаю, ответит и на 1-й.

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

Пример:

clear
clc

array_name = { [0] [2] 'X';
    [4] [1] 'X';
    [9] [7] 'A' ;
    [9] [1] 'X'  ;
    [4] [4] 'B'}

%// Check for string 'X' in the cell array.
FindX = regexp('X',array_name(:,end))

Выводом является ячейка, содержащая логические индексы для совпадений:

FindX = 

    [1]
    [1]
    []
    [1]
    []

Затем проверьте наличие непустых ячеек, т. е. ячеек, имеющих значение 1; совпадение

Idx = ~cellfun(@isempty,FindX);

Idx =

     1
     1
     0
     1
     0

Затем можно использовать логическое индексирование в исходном массиве ячеек:

OutRows = array_name(Idx,:)

OutRows = 

    [0]    [2]    'X'
    [4]    [1]    'X'
    [9]    [1]    'X'

Вы могли бы использовать тот факт, что strcmp работает с массивами ячеек и возвращает a 0, если один из его аргументов не является строкой (а также если строки разные). Итак,

  • Для вопроса (1):

    result1 = strcmp(array_name,'X');
    

    Что дает, в вашем примере,

    result1 =
         0     0     1
         0     0     0
         0     0     0
         0     0     1
         0     0     0
    
  • Для вопроса (2):

    result2 = array_name(strcmp(array_name(:,3),'X'),:);
    

    Что дает

    result2 = 
        [0]    [2]    'X'
        [4]    [1]    'X'
        [9]    [1]    'X'
    
Преимущество этого подхода заключается в том, что он работает даже в том случае, если столбец 3 не содержит только строки. Для например,
array_name = { [0] [2] 'X' ; 
               [4] [1]  5 ; 
               [9] [7] 'A' ; 
               [9] [1] 'X' ; 
               [4] [4]  6 };

result1 =
     0     0     1
     0     0     0
     0     0     0
     0     0     1
     0     0     0

result2 = 
    [0]    [2]    'X'
    [9]    [1]    'X'