Using the "find" function with cell arrays in MATLAB?
131 次查看(过去 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.
0 个评论
回答(2 个)
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 个评论
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
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)
0 个评论
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Logical 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!