简体   繁体   中英

Matlab how to 'sort' the elements of an entire cell array and access the largest values

So I am aware that using the sort(array, 'descend') function in Matlab will sort an array into descending order, with the return result being [values, indices].

I need to get the largest values from an entire cell array, edit them, then place them back into their original places.

For example:

%dst is a 1x5 cell
d1=dst{1};
d2=dst{2};
d3=dst{3};
d4=dst{4};
d5=dst{5};
%d1-d5 are all 512x512x16 double 

I can use [d1SortedValues, d1SortedIndices] = sort(d1(:),'descend'); to get the sorted array and indices for each double cell array d1-d5 BUT I need to do something equivalent to [dstSortedValues, dstSortedIndices] = sort(dst(:),'descend'); so that I can access the highest magnitude elements.

ie for each double array I can do the following to access the highest value in d1.

d1(d1SortedIndices(1)) = d1(d1SortedIndices(1)) + value;

How to get the highest values in the entire 1x5 cell?

Thanks!

Edit based on new information you put in comments:

If you want to find the position of N largest values and replace or modify them, the ind2sub function can help you greatly. Basically:

  • put all your values (of all the cells) in a linear vector.
  • sort the vector and get the indices you want (the N max elements)
  • convert the indices find above into their actual "in cell/in array" position
  • Modify the value in place

It looks like that:

nMaxVal2find = 30 ; %// how many largest element N to locate/modify

fullArrayC = cellfun(@(a) a(:), dst , 'uni',0) ; %// cell array of linearised vectors
fullArray = cat(1, fullArrayC{:} ) ;             %// linear array of all the values
[sVals,sInds] = sort(fullArray,'descend') ;      %// sort the full array

%// Keep only N largest values
Val2keep = sVals(1:nMaxVal2find) ;
ind2keep = sInds(1:nMaxVal2find) ;

%// find all the "in cell" position of the N largest elements
[ii,jj,kk,icell] = ind2sub( [size(dst{1}) numel(dst)] , ind2keep ) ;

%// loose loop to replace elements / can be improved
for idx=1:numel(icell)
%//     dst{ic(iCell)}(ii(iCell),jj(iCell),kk(iCell)) = dst{ic(iCell)}(ii(iCell),jj(iCell),kk(iCell)) * 10 ;
    dst{icell(idx)}(ii(idx),jj(idx),kk(idx)) = Val2keep(idx) * 10 ;
end

If you want to find the highest value ( meaning you are sure to have only one largest value ) of your whole cell array, you can directly get the index with max .

To use that on a cell array you can use cellfun . Once located, you can modify the value directly in place (instead of having to reorder your arrays twice).

%// find the maximums of each cell, and their linear index
[maxVals,maxInds] = cellfun( @(a) max(a(:)) , dst(:) , 'uni',0) ;

%// find the absolute maximum and in which cell it was
[maxV,maxCellInd] = max( cell2mat(maxVals) ) ;

%// return the (i,j,k) style index of the maximum value
[ii,jj,kk] = ind2sub( size(dst{maxCellInd}), maxInds{maxCellInd} ) ;

%// modify the value in place
dst{maxCellInd}(ii,jj,kk) = dst{maxCellInd}(ii,jj,kk) * 10 ; %// the value times 10

Notes:

  • in case there are multiple elements at the same maximum level, max will only return the index of the first element.
  • If you really need/want to use sort , you can also use that with cellfun on the whole cell array.

Last note: I used that code to generate sample data:

for ic=1:5
    dst{ic} = rand(5,5,3) ;
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM