How to apply this for-loop containing '<', designed for a scalar array, to several scalar arrays in a cell array?

1 visualización (últimos 30 días)
Hello, i have the code below which was designed to be applied on a 100x6 scalar array called x and contains '>'. I wish to apply it on 4 scalar arrays 100x6 which are in a column as a cell array. Example: Cell :{ [100,6]
[100,6]
[100,6]
[100,6] }
for j=1:6
q=quantile(x(:,j),0.97);
id=find(x(:,j)>(q));
x(id,j)=NaN;
end
Thanks.

Respuesta aceptada

dpb
dpb el 26 de Jun. de 2022
Editada: dpb el 26 de Jun. de 2022
There was no need for the loop in the original code -- quantile is already vectorized as are almost all ML-supplied functions. The first code should have been written as
Q=0.97; % use variables don't bury magic numbers inside argument lists
q=quantile(x,Q); % find the limit
x(x>q)=nan; % set the exceeding locations
If it is needed to know/have the values of q, then then iterate over the cell array with the above two lines, dereferncing each cell content in turn.
If the values of q aren't needed later, then the whole thing can be turned into a one liner...
x(x>quantile(x,Q))=nan;
and you can iterate over the cell array with the single expression.
But, NOTA BENE: it takes only the loop over the cell array, NOT a double loop as would wrapping the original code in another loop.
Assume the cell array containing the arrays is C --
Q=0.97;
for i=1:numel(C)
q{i}=quantile(C{i}); % compute the quantiles by column
C{i}(C{i}>q{i})=nan; % fixup the cell array
end
NB: the dereferencing of the cell array C with "the curlies" {} to obtain the underlying array, then the subscripting expression inside "regular" parentheses () to address elements within the array.
NB Second: the above overwrites the original cell array; if need to keep the original data, then use another variable to make a copy first before running the loop and use it instead is simplest and fastest (although the original also overwrites so this may be moot point).
See the documentation on cell arrays for the details on the syntax for using and addressing cell arrays.

Más respuestas (1)

Voss
Voss el 26 de Jun. de 2022
Editada: Voss el 26 de Jun. de 2022
Wrap that loop in another loop:
Cell = { rand(100,6); rand(100,6); rand(100,6); rand(100,6) };
for k = 1:numel(Cell)
x = Cell{k};
for j=1:6
q=quantile(x(:,j),0.97);
id=find(x(:,j)>(q));
x(id,j)=NaN;
end
Cell{k} = x; % store the result back in Cell
end
By the way, if something is scalar, then it can't be 100x6; scalar means 1x1.
  10 comentarios
Voss
Voss el 26 de Jun. de 2022
I guess I should've said: to be consistent with the original (loop) code, set the dim argument to 1.
dpb
dpb el 26 de Jun. de 2022
Editada: dpb el 26 de Jun. de 2022
Understand/understood -- I was just being me! :)
It would be consistent with the original coding as done; agreed; I had simply observed that from that code it seemed the case of a single row would have no meaning and so not ever arise in practice but, logically, if it were the case then the only way in which any quantile would have any chance of meaning anything would be over the vector...but it is probably also true that the various columns represent different variables and so mixing across them is also not a reasonable thing to do in practice...
My coding habits would be to have uncovered there being insufficient data on entry into the routine and aborted then before ever getting to this code section.
But, if the intent is only to duplicate the original code logic and make no changes even to edge cases, then the optional argument would do that, yes.

Iniciar sesión para comentar.

Categorías

Más información sobre Matrix Indexing en Help Center y File Exchange.

Productos


Versión

R2018a

Community Treasure Hunt

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

Start Hunting!

Translated by