Calling a function option using cellfun

Hey guys,
I'm trying to use the function datestr on a cellmatrix using the option 'local'.
My code without the 'local' option looks something like this:
C = cellfun(@datestr, C, 'UniformOutput', false);
Where do I place the option in this piece of code?
I'm using Matlab2012a
Thanks

 Risposta accettata

You need to create a new function that only takes one input argument (the cell array element) and then call datestr with that argument and the 'local' option. This can be done all in one go with an anonymous function:
C = cellfun(@(x) datestr(x, 'local'), C, 'UniformOutput', false);

5 Commenti

Thanks mate, one more question. Is it good practise to call the anonymous function x? Should I call it something else? Obviously my cellarray isn't called C either...
Stephen23
Stephen23 il 21 Dic 2017
Modificato: Stephen23 il 21 Dic 2017
"Is it good practise to call the anonymous function x? "
The anonymous function in Guillaume's answer is not named anything, nor is it allocated to any named variable: it is simply provided as the first argument to cellfun. The anonymous function does define one input argument named x.
"Should I call it something else?"
If you are asking about that input argument, then you can rename it if you want to. What is the imperative for this?
"Obviously my cellarray isn't called C either..."
Your question shows a cell array named C.
Jos (10584)
Jos (10584) il 21 Dic 2017
Modificato: Jos (10584) il 21 Dic 2017
x is just the name of a variable. You can rename it to any other valid variable name, like
MyCellArrayNotCalledC_output = cellfun(@(whateveryoulike) datestr(whateveryoulike, 'local'), MyCellArrayNotCalledC_input , 'UniformOutput', false);
Thanks! I thought the function itsself was called x. I understand now.
As Stephen's said, an anonymous function, by definition, has no name. x is the name given to the input argument of the anonymous function and can be anything.
Now to answer your question is it good practice...
Good practice for naming variables is to give them names that clearly describe what's in them. With that in name x and C are extremely poor variable names.
However, for anonymous functions, the variable scope is only the next few characters that follows its declaration. In my answer x only exists as far as the end of datestr(x, 'local'), so it's immediately clear that its sole purpose is to pass the input to datestr with a 'local' option, so I don't worry about the name.
C however lives on more than one line, so you should absolutely use a better name for that variable.

Accedi per commentare.

Più risposte (1)

realize it's been a few years, but just came across this and noticed Matlab didn't have a way of passing or implicitly expanding a parameter in cellfun (except for a very few specific functions as mentioned in the help). It looks clunky, but the following also works for parameters, passing constants, etc., as additional cell arrays without calling an anonymous function, which has a bit of a performance penalty (understanding the memory impact this could imply for very large cell arrays). I assume it can also be done for non-constant parameters, but not sure you'd see the same speedup:
abc = {magic(2), magic(3), magic(4)}
abc =
3×1 cell array
{2×2 double}
{3×3 double}
{4×4 double}
def = cellfun (@(x) sum(x,2), abc, "UniformOutput", false) % Guillaume's anonymous function method
def =
3×1 cell array
{2×1 double}
{3×1 double}
{4×1 double}
def{:}
ans =
4
6
ans =
15
15
15
ans =
34
34
34
34
def = cellfun (@sum, abc, num2cell(2*ones(size(abc))), "UniformOutput", false) % cell expansion method
def =
3×1 cell array
{2×1 double}
{3×1 double}
{4×1 double}
def{:}
ans =
4
6
ans =
15
15
15
ans =
34
34
34
34
a quick and very unscientific speed check seems to indicate it's a bit faster, although you'd want to check before scaling to large arrays, or more than one parameter
tic;
for idx = 1:100000
cellfun(@(x) sum(x,2), abc,"UniformOutput",false);
end
toc
Elapsed time is 4.017116 seconds.
tic,
for idx = 1:100000
cellfun(@sum, abc, num2cell(2*ones(size(abc))),"UniformOutput",false);
end
toc
Elapsed time is 1.217712 seconds
I would assume for nontrivial numeric parameters, you could use repmat instead of num2cell, but that seems to carry more overhead:
tic
for idx = 1:100000
cellfun(@sum, abc, repmat({2}, size(abc)),"UniformOutput",false);
end
toc
Elapsed time is 4.367002 seconds.

Categorie

Community Treasure Hunt

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

Start Hunting!

Translated by