2015-10-05 3 views
1

Предположим, у меня есть ячейки массивов одного и того же размера, напримерНайти соответствующий массив в ячейке

arr = {[1 NaN 2 ], ... 
     [NaN 4 7 ], ... 
     [3 4 NaN] }; 

и у меня также есть вектор, например

vec = [1 2 2]; 

Как найти соответствующий элемент ячейки, который соответствует вектору vec. Соответствие означает, что записи в одном и том же месте одинаковы, за исключением NaN s?

Для этого конкретного конкретного человека vec Я хотел был бы вернуть 1, так как он соответствует первой строке.

Другой вектор [5 4 7] вернется 2.

Векторы, которые не соответствуют [7 7 7], и векторы, которые соответствуют более чем одной записи, например [3 4 7], должны вызывать ошибку.

Обратите внимание, что вектор [3 7 4] не соответствует второму вводу, потому что заказ важен.

+0

Так, 'NaN' для вас означает "все" Rigth? –

+1

Да. 'NaN' произвольно выбирается. Для этого я мог бы выбрать «42», но это казалось неинтуитивным. – Wauzl

+2

Все ли ячейки всегда соответствуют векторам одинаковой длины? – Divakar

ответ

1

Для каждого гальванического элемента, просто проверить, если

all(isnan(cellElement) | cellElement == vec) 

правда, что означает, что вы нашли совпадение. Если вы преобразуете свою ячейку в матрицу checkMatrix с несколькими строками и каждой строкой, соответствующей одному cellElement, вы даже можете сделать это, не выполняя цикл, повторяя vec вертикально и сравнивая всю матрицу за один шаг. Вы должны сказать все(), чтобы проверить по размерности 2, а не размерности 1 и найти() обнаружить все матчи, например, так:

find(all(... 
    isnan(checkMatrix) | checkMatrix == repmat(vec,size(checkMatrix, 1),1) ... 
    , 2)); % all() along dimension 2 
+0

Это не вызывает ошибку для отсутствия или нескольких совпадений, но это можно легко проверить после 'find'. – Wauzl

1

Смотрите, если это bsxfun подход, основанный работает для вас -

A = vertcat(arr{:}); 
matching_ind = find(all(bsxfun(@eq,A,vec(:).') | isnan(A),2)) %//' 
if numel(matching_ind)~=1 
    error('Error ID : 42.') 
else 
    out = matching_ind(1); 
end 
+0

Это не работает. Например, 'vec = [3 7 4]' "соответствует" второй и третьей ячейке, где это не должно. – Wauzl

+0

@Wauzl Проверьте отредактированный код? – Divakar

+0

Мне нравится использование 'bsxfun (@eq, ...)'. – Wauzl

1

Так я думал об этом и пришел с этим:

matching_ind = @(x, arr) find(... 
    cellfun(@(y) max(abs(not(x-y==0).*not(isnan(x-y)))),... 
      arr)     == 0); 

inds = matching_ind(vec, arr); 

if length(inds) ~= 1 
    error('42'); 
end