2016-07-21 3 views
1

В контексте написания определенной функции, я в следующем примере матрица:MATLAB найти первые элементы в столбцах массива

temp = 

    1  2  0  0  1  0 
    1  0  0  0  0  0 
    0  1  0  0  0  1 

Я хочу, чтобы получить массив, каждый элемент указывает номер элемента из всех ненулевых элементов, которые начинают этот столбец. Если столбец пуст, элемент должен соответствовать следующему непустому столбцу. Для матрицы temp, результат был бы:

result = [1 3 5 5 5 6] 

Поскольку первый ненулевой элемент начинает первый столбец, третий начинает второй столбец, пятый начинает пятую колонну и шестой начинается шестой столбец.

Как я могу выполнить эту операцию для любой общей матрицы (такой, которая может содержать или не содержать пустые столбцы) в векторном виде?

+0

Я бы не назвал колонку, заполненную нулями «Пустая» столбца. Пустой столбец будет, например, средний столбец [[1; 3], [], [2; 4]] – Nibor

+0

@Nibor MATLAB не обрабатывает матрицы неправильной формы, например, имеет промежуток в середине. В юниверсе MATLAB наличие столбца всех нулей является правильной терминологией для пустого. – rayryeng

+1

Я предполагаю, что вы считаете свои ненулевые элементы в основном порядке столбцов? – excaza

ответ

5

Код:

temp = [1 2 0 0 1 0; 1 0 0 0 0 0; 0 1 0 0 0 1] 
t10 = temp~=0 
l2 = cumsum(t10(end:-1:1)) 
temp2 = reshape(l2(end)-l2(end:-1:1)+1, size(temp)) 
result = temp2(1,:) 

Выход:

temp = 
    1  2  0  0  1  0 
    1  0  0  0  0  0 
    0  1  0  0  0  1 

t10 = 
    1  1  0  0  1  0 
    1  0  0  0  0  0 
    0  1  0  0  0  1 

l2 = 
    1  1  1  1  1  2  2  2  2  2  2  2  3  3  4  4  5  6 

temp2 = 
    1  3  5  5  5  6 
    2  4  5  5  6  6 
    3  4  5  5  6  6 

result = 
    1  3  5  5  5  6 

значения печати каждого шага может быть яснее, чем мое объяснение. В основном мы используем cumsum, чтобы получить идентификаторы ненулевых элементов. Поскольку вам нужно знать идентификатор до достижения элемента, это сделает обратный cumsum. Тогда остается только отменить идентификационные номера.

+0

Возможно, вы захотите отрегулировать второй последний оператор для учетной записи для произвольных размерных матриц, а не только '3 x 6'. – rayryeng

+0

@rayryeng thx за предложение – kangshiyin

+0

Очень умный! Может быть, с некоторым объяснением, а не с дампом прямого кода :) – excaza

2

Вот еще один способ:

temp = [1 2 0 0 1 0; 1 0 0 0 0 0; 0 1 0 0 0 1]; % data 
[~, c] = find(temp); % col indices of nonzero elements 
result = accumarray(c, 1:numel(c), [], @min, NaN).'; % index, among all nonzero 
    % values, of the first nonzero value of each col; or NaN if none exists 
result = cummin(result, 'reverse'); % fill NaN's using backwards cumulative maximum