2012-01-21 5 views
3

У меня есть матрица, каквектор на основе элиминации нули из матрицы

frequencyarray = 

    697 697 697 697 697 697  0  0 697 
     0  0  0  0  0  0 770 770  0 
     0  0  0  0  0  0  0  0  0 
     0  0  0  0  0  0  0  0  0 
    1209 1209 1209 1209 1209 1209 1209 1209 1209 
     0  0  0  0  0  0  0  0  0 
     0  0  0  0  0  0  0  0  0 

я сейчас хотел бы устранить все нули на векторной основе из него и получить этот

frequencyarray2 = 

    697 697 697 697 697 697 770 770 697 
    1209 1209 1209 1209 1209 1209 1209 1209 1209 

Я только хотите сделать это, если в векторе есть ровно два ненулевых числа. Если вектор имеет больше или меньше двух ненулевых чисел, их следует заменить нулями.

Поэтому, если у меня есть что-то вроде:

frequencyarray = 

     0  0 697 697 
     0  0 770 770 
     0  0  0  0 
     0  0  0  0 
    1209 1209 1209 1209 
     0  0  0  0 
     0  0  0  0 

ответ должен быть:

frequencyarray2 = 

     0  0  0  0 

Использование находку, это не работает, он просто делает все на одном векторе. Я думал об использовании find, а затем изменил форму. Но это работает только в том случае, если ровно два числа не равны нулю на вектор.

Если возможно, я бы хотел избежать циклов. У столбцов нет никакой связи между ними.

Любая идея ценится

+0

Не простая задача - Вы уверены, что хотите/должны решить ее вектор на основе? – bdecaf

+0

Хм хорошо ... это только результат предыдущей части. я мог подумать об изменении его, хотя. Думаю, я просто воспользуюсь тем, если нет малбаб-волшебного способа сделать это. – Atmocreations

+1

ну, это две части. как я вижу, вы можете обрабатывать линии, векторизованные, но вам все равно придется перебирать строки по строкам. поэтому возможен «полувекторный» подход. Также Али показал вам, что вы нашли «кандидатские» линии векторизованными. – bdecaf

ответ

0

Ну ... Я решил эту проблему. Даже не так, как я хотел, но он работает ... И это не должно быть сверхбыстро.

Вот мое решение, если кто-то интересуется:

function [collapsed] = collapse(frequencies) 
    fsize = size(frequencies,2); 
    collapsed = zeros(2,fsize); 
    for it=1:fsize 
     col = frequencies(:,it); 
     nonzero = frequencies(find(col != 0)); 
     if (size(nonzero,1) == 2) 
      collapsed(:,it) = nonzero; 
     endif 
    endfor 
endfunction 
+0

Не должно быть 'nonzero = col (find (col! = 0))'? Также Matlab имеет булевское индексирование, поэтому вы можете написать 'nonzero = col (col! = 0)'. 'col! = 0' возвращает булевский массив и A [B], когда B является булевым массивом того же размера, что и A, возвращает элементы A, где B - True. –

+0

hmm не проверил это еще. моя реализация работает, и проект не стоит, черт возьми, более пристальный взгляд;) хороший комментарий. – Atmocreations

+0

Я не думаю, что 'отличное от нуля = частоты (find (col!= 0)) 'может работать, вы всегда будете индексировать первый столбец. Я думаю, вы либо хотите 'ненулевые = частоты (find (col! = 0), it);' или 'nonzero = col (find (col! = 0))'. –

2

Вы можете использовать sum и find вместе. Что-то вроде:

frequencyarray(sum(frequencyarray==0)==2) 
+0

На самом деле вы не должны использовать find в этом случае. Вместо этого логическая индексация. Ваше решение суммирует индексы, найденные в режиме поиска - только для достижения 2, когда только 0 находится в индексе 2. – bdecaf

+0

@bdecaf вы правы, отредактированы. – Ali

1

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

all((frequencyarray(i,:) == 0) & (frequencyarray(i+1,:) ~= 0)) 

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

Чтобы присоединиться к линии, которые вы могли бы использовать:

i_cand = (frequencyarray(i,:) == 0 
joined_line = frequencyarray(i,:); % start 
joined_line(~icand) = frequencyarray(i+1,~icand); % end of joining 
Смежные вопросы