How to replace zeros with other value in a big matrix fast

36 visualizaciones (últimos 30 días)
Hi all, I have a programming efficiency question. I would like to replace zero value of a big matrix with mean value of it. I know how to do it.However, it takes forever. I do not know if I did it wrong or it actually takes so much time. I am wondering if there is a better way to do it for a big matrix as big as 3320*3320. Here is my code. Assume A is the 3320*3320 matrix. I wrote only
A(A==0)=mean(mean(A));
Please let me know if I did it wrong. If I did it right, can somebody suggest any faster way to do the same thing ? Thank you very much,

Respuesta aceptada

Matt Fig
Matt Fig el 14 de Abr. de 2011
Don't double call these functions (MAX,MIN,SUM,MEAN,etc.). Learn to use the colon, it is your friend!
A(~A(:))=mean(A(:));
This will be somewhat faster. If you need even more speed, replace the call to mean with its definition.
A(~A(:)) = sum(A(:))/numel(A);
The thing is, with a very large array, it might just take some time!
Here is how I timed these, BTW. You can play around with other options as well! Run the function 3 times (the first time warms it up after a save). The time will print to the command window.
function [] = write_ones()
T1 = 0; % Time two different approches
T2 = 0;
for ii = 1:5
A = round(rand(3320))>.75;
tic
A(A==0)=mean(mean(A));
T1 = T1 + toc;
clear A
A = round(rand(3320))>.75; % A new A.
tic
A(~A(:)) = sum(A(:))/numel(A);
T2 = T2 + toc;
end
[T1 T2]
  7 comentarios
Jan
Jan el 15 de Abr. de 2011
James' Mex function profits from omitting the boundary checks, while Matlab seems to check the boundary for each single index - even for logical indexing. See http://www.mathworks.com/matlabcentral/newsreader/view_thread/295653 . Therefore a Mex can create partial copy using logical indexing about 3 times faster than in Matlab (Matlab 2009a, MSVC, even small arrays).
Jan
Jan el 28 de Jun. de 2012
accpeted by JSimon

Iniciar sesión para comentar.

Más respuestas (1)

Teja Muppirala
Teja Muppirala el 15 de Abr. de 2011
Matt, I had originally thought the same thing (using a colon on the right hand side also might be faster), but I'm not able to reproduce your results: I consistently get that the second case is faster. (0.18s vs 0.15s)
function colontest
A = rand(3320); A(A < 0.9) = 0; B = A+0;
tic; A(~A(:)) = sum(A(:))/numel(A); toc;
tic; B(B == 0) = mean(mean(B)); toc;
  5 comentarios
Jan
Jan el 15 de Abr. de 2011
My observations suggest that MEAN(X) is parallelized in modern Matlab version: The columns are processed in different threads for large matrices, while MEAN(X(:)) seems to run in a single thread. Therefore MEAN(MEAN(X)) can be faster.
Andrei Bobrov
Andrei Bobrov el 15 de Abr. de 2011
Dear Jan, my "research" :)
1. compare mean(...(:)) and mean(mean(...)) ->
>> A = +(round(rand(5000))>.75);tic,A(A(:)==0) = mean(mean(A));toc
Elapsed time is 0.528957 seconds.
>> A = +(round(rand(5000))>.75);tic,A(A(:)==0) = mean(A(:));toc
Elapsed time is 0.528977 seconds.
2. compare use '~' and '==' ->
>> A = +(round(rand(5000))>.75);tic,A(~A) = mean(mean(A));toc
Elapsed time is 0.669978 seconds.
>> A = +(round(rand(5000))>.75);tic,A(A==0) = mean(mean(A));toc
Elapsed time is 0.531413 seconds...

Iniciar sesión para comentar.

Categorías

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

Community Treasure Hunt

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

Start Hunting!

Translated by