Reduce computational time when calling cellfun

1 Ansicht (letzte 30 Tage)
Ole Hansen
Ole Hansen am 9 Jul. 2012
I have:
for i=1:length(cellarray)
id1=cellfun(@(x)any(ismember('1',x)),cellarray{i})
id2=cellfun(@(x)any(ismember('2',x)),cellarray{i});
id3=cellfun(@(x)any(ismember('3',x)),cellarray{i});
...
end
which I would like to rewrite as something like:
for i=1:length(cellarray)
value=cellfun(@(x)x(1),cellarray{i})
id1=any(ismember('1',value));
id2=any(ismember('2',value));
id3=any(ismember('3',value));
...
end
in order to try to reduce computational time. Here,
cellarray={'AA','KK','AKs','QQ','AKo',...};
The problem is, that the first approach correctly evaluates each cell and return the results into a vector id1, id2, ... whereas the second approach considers all elements in the cell array simultaneously. Changing "any(ismember(...))" to "ismember(...)" also only evaluates the entire array.
How do I make sure that each cell is evaluated? Say the cell array has 5 elements, then id1 should have 5 elements containing 0's or 1's.
  1 Kommentar
Jan
Jan am 9 Jul. 2012
Bearbeitet: Jan am 9 Jul. 2012
Are the elements of cellarray are strings? No, sorry, they are cells of cell strings, correct?
Please do not let us guess, but provide some sample data in valid Matlab syntax. And please insert them by editing the question, not as comment or answer.
Comments to the code:
  1. strfind is much more efficient than ismember(CHAR).
  2. Creating a bunch of variables called id1, id2, ... is a bad programming practize. id{1}, id{2}, ... would be more convenient.
  3. id1=any(ismember('1',x)),value) contains 2 left and 3 right parenthesis. Please fix this.

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

Jan
Jan am 9 Jul. 2012
Bearbeitet: Jan am 9 Jul. 2012
for i = 1:length(cellarray)
S = cellarray{i};
id1 = any(strfind(S, '1'));
id2 = any(strfind(S, '2'));
id3 = any(strfind(S, '3'));
...
end
If the cell array is very large and you look for a few characters only, this approach could be more efficient, when you want to process the complete cell without a loop:
id1 = ~strcmp(cellarray, strrep(cellarray, '1', '*'));
...
  3 Kommentare
Jan
Jan am 9 Jul. 2012
Bearbeitet: Jan am 9 Jul. 2012
ISMEMBER is slow, because it has a large overhead, e.g. to sort the characters in the string. If the strings have less than about 20 characters, this wastes time. Because you have asked for a faster method, I suggested a faster method.
Let me repeat, that it would be helpful to create an helpful answer efficiently, when you post all relevant details. What kind of output do you need? What is the purpose of cellfun(@(x)x(1),cellarray{i})?
Why does cellfun(@(x)any(ismember('1',x)),cellarray{i}) work at all, if cellarray is a cell string? Then cellarray{i} is a string, and not a apropriate input for cellfun().
Summary: At first I did not know the inputs. Now, after you have posted the input, I do not understand how your program could work with it. The wanted output is still not defiend exactly. So how do you expect us to accelerate your function?
Please, Ole, post a running example which we can run using copy&paste. This is essential for speed improvements.
Ole Hansen
Ole Hansen am 10 Jul. 2012
Bearbeitet: Ole Hansen am 10 Jul. 2012
I used strfind instead of ismember and found a reduction in computational speed by around 25% I assume this reduction is specifically for my script.
I cannot answer all of your questions at hand; there are some things I do not understand as of now - I will return shortly.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Kategorien

Mehr zu Characters and Strings finden Sie in Help Center und File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by