Using the "find" function with cell arrays in MATLAB?

132 次查看(过去 30 天)
Hello, I have a cell that contains a lot of data. Let's say this cell, c, has 10 matrices, each being 100x2 (i.e., it is 2-dimensional). So here C= {[100x2], [100x2],...[100x2]}. What I need to do is search each array inside this cell, and find where the value of the first column is less than 401, and also greater than 399 (e.g., find(c(:,1)>399 & c(:,1)<401), although this is probably wrong). I am exclusively focusing this analysis on only the first column of each matrix. Importantly, I need to be able to store the indices where these occur in a new variable. My question: is there a simple way to do this using the "cellfun" function in MATLAB? I'm still getting used to this function and I'm having a hard time telling what I can and can't do with it, or when it's better to just use a for loop. Is there perhaps an even simpler method I'm not aware of? I would really appreciate any help.

回答(2 个)

Star Strider
Star Strider 2015-2-25
I’m not opposed to using cellfun, but it might be easier in your situation to extract them to double arrays with cell2mat, and then do the find operations on them there. Cell arrays are quite useful and I use them frequently, but sometimes it’s easier to extract the data as double arrays. Yours would appear to be one.
  2 个评论
John Alperto
John Alperto 2015-2-25
Wait, you suggest I extract each individual part of the cell into a different array? Wouldn't I still have to use a cell to keep them all in one variable? Or are you suggesting I do a for loop and store each resulting vector into a different variable? I guess I'm not picturing what you're saying exactly, sorry.
Star Strider
Star Strider 2015-2-25
That you have a compound search condition:
find(c(:,1)>399 & c(:,1)<401)
might make converting them to double and then using find is easiest. You can use a cell array to keep track of the indices find returns. A for loop would make this easier. Loops really aren’t evil!
If you want to use cellfun, these simple bits of archived code might offer an option:
First Example:
MyArray = {3 [] 3 []};
idx = find(cellfun(@isempty, MyArray));
MyArray(idx) = {0};
Second Example:
x = randi(10, 15, 10);
x(:,5) = 99.9*ones(15,1);
Neg = {x};
Idx = cellfun(@(x) find(x == 99.9), Neg, 'Uni',0);
The for loop might still be necessary in order to process all of them efficiently.

请先登录,再进行评论。


Guillaume
Guillaume 2015-2-25
One possible way: (prerequisite: all the matrices in C are 2d and the same size):
allmatrices = cat(3, C{:});
firstcolumns = squeeze(allmatrices(:, 1, :));
[rowindices, matrixnumber] = find(firstcolumns > 399 & firstcolumns < 401);
%to redistribute the above two values in a cell array if wanted:
rows = accumarray(matrixnumber, rowindices, [numel(C) 1], @(v) {v})
Or using cellfun:
rows = cellfun(@(m) find(m(:, 1) > 399 & m(:, 1) < 401), C, 'UniformOutput', false)
This may or may not be slower than the other method (but does not have any prerequisite)

类别

Help CenterFile Exchange 中查找有关 Matrix Indexing 的更多信息

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by