Как выделить или идентифицировать столбец с определенным значением в матрице?

Я хотел бы выделить или идентифицировать столбец в матрице с определенным значением в MATLAB. Предположим, у меня есть матрица A = [1 0 1 1 0 1; 1 1 0 0 0 1; 1 0 1 1 0 1; 0 1 1 0 0 1].

Результатом приведенной выше матрицы является 5-й столбец, так как он содержит все нули. Мне также интересно, могу ли я выделить полученный столбец для идентификации. Пожалуйста помогите. У меня есть очень большая матрица для работы по применению этого принципа.


person Azhar    schedule 23.09.2015    source источник
comment
Что вы имеете ввиду под выделением?   -  person Stewie Griffin    schedule 23.09.2015
comment
Возможно, вы захотите использовать spy для отображения расположения ненулевых элементов в матрице. В этот сюжет можно было бы добавить какую-то изюминку. Это то, что вы имеете в виду?   -  person Wauzl    schedule 23.09.2015
comment
@Wauzl Может быть, то, что ты говоришь, это то, чего я хочу. Но я ничего не знаю о spy и его использовании.   -  person Azhar    schedule 23.09.2015


Ответы (3)


Выделение красным (stderr)

Просто для проверки концепции вы можете выделить некоторые данные в командном окне, хотя я бы не советовал делать это на самом деле. Рассмотрим следующий код:

A=randi(10,8);
%ind = find(all(A==0,1),1) %for actual data
ind = 5; %manual choice for demonstration

for k=1:size(A,1)
    fprintf('%5d   ',A(k,1:ind-1));
    fprintf(2,'%5d   ',A(k,ind));
    fprintf('%5d   ',A(k,ind+1:end));
    fprintf('\n');
end

Сначала мы создаем фиктивную матрицу для демонстрационных целей и выбираем столбец ind для выделения. Затем мы идем от строки к строке в A, мы используем fprintf(...) для записи невыделенных значений в заданном формате, затем используем fprintf(2,...) для записи в stderr красным цветом, затем записываем оставшуюся часть строки , затем новая строка. Обратите внимание, что по какой-то причине fprintf(2,...) не будет выделять последний символ, я думаю, потому что обычно это \n, и никто не заметил, что там отсутствует подсветка.

Кроме того, вы можете поиграть с форматами внутри fprintf в соответствии с вашими потребностями. Если вам нужно печатать с плавающей запятой, может подойти что-то вроде '%10.8f'. Или '%g'. Суть в том, чтобы иметь фиксированную ширину + точность для печати, чтобы получить красивые столбцы.

Для полноты вы можете сделать обработку нескольких выделяемых столбцов еще более запутанной:

A=randi(10,8);
%ind = find(all(A==0,1)) %for actual data
ind=[5 2];

fprintf('A = \n\n');
for k1=1:size(A,1)
    for k2=1:size(A,2)
        if ismember(k2,ind)
            fprintf(2,'%5d   ',A(k1,k2));
        else
            fprintf('%5d   ',A(k1,k2));
        end
    end
    fprintf('\n');
end
fprintf('\n');

Я также добавил несколько дополнительных распечаток, чтобы сделать его красивее. Результат: красная подсветка

Мелирование синим цветом (ссылки)

В качестве запоздалой мысли после некоторого обсуждения с Луис Мендо, я решил, что стоит немного перестараться, пока мы тут. Вы можете превратить свои числа в выделенные синим цветом и подчеркнутые гиперссылки, используя встроенный анализ HTML-тега <a href="URL">link</a>, реализованный как в disp, так и в fprintf. Вот соответствующий код:

A=randi(10,8);
ind=[5 2];

fieldlen=5; %width of output fields, i.e. 5 in '%5d'

fprintf('A = \n\n');
for k1=1:size(A,1)
    for k2=1:size(A,2)
        if ismember(k2,ind)
            fprintf([repmat(' ',1,fieldlen-length(num2str(A(k1,k2)))) '<a href="matlab:">%d</a>   '],A(k1,k2));
        else
            fprintf('%5d   ',A(k1,k2));
        end
    end
    fprintf('\n');
end
fprintf('\n');

Это превратит элементы выделенного столбца (столбцов) в строки формы '<a href="matlab:">3</a>' для примера значения 3.

Еще одна хитрость заключается в том, что гиперссылки, начинающиеся с matlab:, анализируются как правильные команды Matlab, которые активируются при нажатии на ссылку. Вы можете попробовать это, набрав disp('<a href="matlab:help help">link</a>') в командном окне. Установив <a href="matlab:">...</a>, мы гарантируем, что ничего не произойдет, когда кто-то нажмет на выделенные числа со значением ссылки.

И еще одно техническое примечание: мы хотим включить в ссылки только фактическое число (а не предшествующие пробелы), поэтому нам нужно вручную проверить длину строки, которую мы собираемся напечатать (используя length(num2str(A(k1,k2)))), и вручную включить остальные пробелов перед числом. Это делается с помощью параметра fieldlen, который я установил в начале: он определяет общую ширину каждого поля печати, т.е. если у нас изначально было fprintf('%5d',...), то для того же эффекта нам нужно установить fieldlen=5;. Результат: введите здесь описание изображения

person Andras Deak    schedule 23.09.2015
comment
@StewieGriffin извините за дополнительную работу, я только что понял, что было бы достаточно весело взломать :) Спасибо! - person Andras Deak; 23.09.2015
comment
Хороший подход. Я печатал аналогичный, который выделяет выбранные столбцы жирным шрифтом. - person Luis Mendo; 23.09.2015
comment
@StewieGriffin@LuisMendo@AndrasDeak Отлично! +1! Мне было интересно, можем ли мы также назвать эти идентифицированные индексы столбцов вместе с цветовым кодированием. Как первый столбец как «a», второй столбец как «b» и так далее... - person Azhar; 23.09.2015

Как насчет объединения find и all, чтобы получить индекс столбца со всеми нулями нравится?

A = [1 0 1 1 0 1; 1 1 0 0 0 1; 1 0 1 1 0 1; 0 1 1 0 0 1];
 
ind = find(all(A==0,1))
ind = 
    5

Второй входной аргумент для all должен указать, что он находится по первому измерению, то есть по строкам. Здесь это не обязательно, но я считаю, что это хорошая практика, поскольку вы всегда уверены, что это правильное измерение. Это особенно важно, если есть сценарии, в которых вы можете получить вектор 1xn вместо mxn.

Создайте цветную матрицу:

Это хак, и я не обязательно его рекомендую, но если вы действительно хотите сделать это в MATLAB, это альтернатива. Кроме того, я думаю, что вы можете много узнать о MATLAB, делая это, так что это может стоить времени.

Вы можете создать цветной график со всеми значениями 1, кроме значений в столбце 5, которые будут 0 (или наоборот, не имеет значения), используя imagesc. Это даст график только с двумя цветами: один для тех значений, которые равны 1, и один для тех, которые равны 0. Вы можете выбрать нужные цвета с помощью colormap. Затем вы создаете сетку, чтобы определить расположение всех значений, которые вы хотите показать, преобразуйте матрицу в строки, используя num2str, и объедините все это. Вам нужно поэкспериментировать, чтобы получить правильные местоположения, так как вы, вероятно, хотите меньше отступов между строками, чем между столбцами. Вы можете использовать этот ответ в качестве руководства. В конце удалите оси. Адаптация должна быть довольно простой, если вы читаете и пытаетесь понять каждую строку указанного ответа.

Простой подход:

У меня очень большая матрица... Такие матрицы часто не рекомендуется включать в отчет. Однако, если вы действительно хотите, я действительно предлагаю вам скопировать и вставить его из обозреватель переменных и в MS Excel (или используйте xlswrite, если вы делаете это более одного раза). Поскольку вы знаете, какой столбец вы хотите окрасить, щелкнуть кнопку цвета должно быть довольно просто.

person Stewie Griffin    schedule 23.09.2015
comment
Ух ты. Такой быстрый ответ. Большое спасибо, Стьюи. Это именно то, что я хотел. Под выделением я подразумеваю добавление цвета для облегчения идентификации. - person Azhar; 23.09.2015

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

A = [1 0 1 0 0 1; 1 1 0 1 0 1; 1 0 1 0 0 1; 0 1 1 1 0 1]; %// matrix
c = [0;1;0;1]; %// column to be matched
nn = find(all(bsxfun(@eq, A, c),1)); %// indices of matching columns
s = cellstr(num2str(A)); %// cell array of strings, one for each row; all same length
for n = nn %// for each matching column, with index n
    s = regexprep(s, '\S+', '<strong>$0</strong>', n); %// make bold n-th value of each cell
end
s = vertcat(s{:}); %// convert back into a char array; all strings have the same length
disp(s); %// display

Результат в этом примере

введите здесь описание изображения

person Luis Mendo    schedule 23.09.2015
comment
Ну, одно можно сказать точно... Мой ответ не должен быть принятым =) +1! - person Stewie Griffin; 23.09.2015
comment
Хотя это кажется более запутанным, оставить stderr в покое всегда хорошая идея:) Я голосую за этот. - person Andras Deak; 23.09.2015
comment
С другой стороны, красный выделяется больше, чем жирный (уже +1) - person Luis Mendo; 23.09.2015
comment
Я также могу представить себе решение, основанное на disp интерпретации тега <a href=..., превращении чисел в симпатичные синие подчеркнутые полужирные ссылки:D - person Andras Deak; 23.09.2015
comment
@AndrasDeak Да ... но что будет целью этих ссылок? Любое предложение? - person Luis Mendo; 23.09.2015
comment
disp('<a href="matlab:">asdf</a>'), кажется, выдает пустую команду Matlab, так что это может быть относительно безопасно :) Продолжайте, если хотите напечатать ее. - person Andras Deak; 23.09.2015
comment
Это была твоя идея. Лучше включить это в свой ответ? - person Luis Mendo; 23.09.2015
comment
Теперь, когда я думаю об этом: вместо пустой ссылки, возможно, имеет смысл добавить команду openvar, чтобы увидеть эту переменную в браузере переменных? Как rayryeng сделал здесь - person Luis Mendo; 23.09.2015
comment
Поскольку целью является только выделение, я думаю, что добавление функции к ссылке сделало бы ее контрпродуктивной. - person Andras Deak; 23.09.2015
comment
@Azhar, просто потому, что он не предназначался для выделения. В правильном языке программирования и системной среде stderr может обрабатываться совершенно по-разному, например, вы можете получить невыделенные и выделенные значения в двух отдельных файлах. Это было бы плохо. Теперь я не верю, что что-то подобное произойдет в Matlab, но использование stderr для такой цели определенно считается злоупотреблением. - person Andras Deak; 24.09.2015
comment
@AndrasDeak это определенно считается злоупотреблением: мы должны правильно использовать это в код-гольфе!! - person Luis Mendo; 24.09.2015
comment
@LuisMendo, это должен быть очень сложный вопрос о гольфе, боюсь, fprintf не такой лаконичный. Но дайте мне знать, если вы используете его: D - person Andras Deak; 24.09.2015