Matlab: вычесть каждое значение в строке из любого другого для каждой строки

У меня есть такие данные: [...

0...0...0...0
6...0...0...0
8...5...2...0
9...8...3...1
0...0...0...0

В каждой строке я хотел бы вычесть каждое значение отдельно от каждого другого в этой строке. Так что я получаю новую матрицу, которая показывает все различия следующим образом: [...

null
0
3...6...3
1...6...8...5...7...2
null

Надеюсь, вы понимаете, что я имею в виду. Я не хочу вычитать 0 из чего-либо (O для меня равно null - если у вас есть способ заменить 0 на null, это нормально). Или, по крайней мере, если это необходимо сделать, я хочу, чтобы эти результаты были отброшены. Но я ДЕЙСТВИТЕЛЬНО хочу, чтобы был какой-то заполнитель, когда строка полностью состоит из 0.

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


person Tom    schedule 28.03.2011    source источник


Ответы (1)


Вы можете использовать PDIST для расчета расстояний:

data =[0 0 0 0
6 0 0 0
8 5 2 0
9 8 3 1
0 0 0 0];
nRows = size(data,1);

%# for speed, preassign 'out'
out = cell(nRows,1);

for r = 1:nRows
   pts = data(r,data(r,:)>0); %# this assumes valid entries are >0
   switch length(pts),
   case 0,
      out{r} = []; %# empty for 'null'
   case 1, 
      out{r}=0; %# zero if only one valid number
   otherwise
      out{r}=pdist(pts'); %'# calculate all differences
   end
end

%# You access elements of a cell array with curly brackets
>> out{3}
ans =
     3     6     3
person Jonas    schedule 28.03.2011
comment
@йонас. еще раз отличный ответ. Как называется выходная матрица в этом? - person Tom; 29.03.2011
comment
@Tom: Я назвал это out из-за отсутствия творчества. - person Jonas; 29.03.2011
comment
@йонас. Но в этом случае кажется, что я не могу отобразить их все сразу, написав 'out' или xlswrite('data.xls',out)? - person Tom; 29.03.2011
comment
@Tom: Да, потому что out — это массив ячеек, который я использую для хранения массивов переменной длины. - person Jonas; 29.03.2011
comment
@ Джонас. Да я вижу. Итак, как же я буду работать со всеми «выходными» строками одновременно? Могу ли я создать новую матрицу с NaN или чем-то еще в нулевых столбцах?? - person Tom; 29.03.2011
comment
@Tom: Что ты хочешь сделать? Во многих случаях cellfun может оказаться полезным. Обратите внимание, что если у вас есть N ненулевых значений в строке, вы получите N(N-1)/2 различий, поэтому, если вы хотите преобразовать out в полный массив, он может стать довольно большим. - person Jonas; 29.03.2011
comment
@йонас. Это потому, что затем мне нужно преобразовать все мои значения в новые значения (каждое отдельно из справочной таблицы), а затем добавить их для каждой строки. Я не возражаю, если полный массив большой, потому что мой исходный массив теперь никогда не превышает 13 столбцов. - person Tom; 29.03.2011
comment
@Tom: при условии, что LUT разрешает прямую индексацию, вы можете преобразовать значения следующим образом: convertedSum = cellfun(@(x)sum(LUT(x)),out). Для каждого элемента в массиве ячеек (т. е. каждой строки) это будет считывать значения из справочной таблицы LUT и суммировать результат. Обратите внимание, что если LUT является массивом, а не функцией, вам нужно что-то сделать с элементами ячейки, содержащими 0, поскольку вы не можете индексировать с 0, если они не являются логическими 0. Обратите внимание, что вы также можете выполнять поиск и суммирование напрямую, без необходимости создавать массив ячеек. - person Jonas; 29.03.2011