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

13 ビュー (過去 30 日間)
Cassie
Cassie 2011 年 4 月 14 日
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,

採用された回答

Matt Fig
Matt Fig 2011 年 4 月 14 日
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 件のコメント
Jan
Jan 2011 年 4 月 15 日
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 2012 年 6 月 28 日
accpeted by JSimon

サインインしてコメントする。

その他の回答 (1 件)

Teja Muppirala
Teja Muppirala 2011 年 4 月 15 日
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 件のコメント
Jan
Jan 2011 年 4 月 15 日
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 2011 年 4 月 15 日
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...

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeMatrix Indexing についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by