Replacing the Maximum Element per Row of a Matrix with a Different Element

2 次查看(过去 30 天)
Hello everyone, I am trying to replace the maximum entry of every row in a matrix with a -1, using MatLab. However, the replacement only occurs in the first row of the matrix, so far this is my code:
m = 240;
n = 5;
for i = 1:m
for j = 1:n
if (num_matrix(i,j) == max(num_matrix,[],2))
num_matrix(i,j) = -1;
end
end
end
Thanks for your help.

采纳的回答

Image Analyst
Image Analyst 2016-8-14
Try using max() and only 1 loop:
num_matrix = randi(99, 5, 10) % Sample data
[rows, columns] = size(num_matrix)
for row = 1 : rows
[maxValue, indexOfMax] = max(num_matrix(row, :));
num_matrix(row, indexOfMax) = -1;
end
% Echo to command window.
num_matrix
  3 个评论
dpb
dpb 2016-8-14
编辑:dpb 2016-8-14
The loop has nothing to do with it, it's a logic error in use of max--
if (num_matrix(i,j) == max(num_matrix,[],2))
you're finding the same maximum location each time because it's operating over the full array and the RHS is a column vector of rows length. Look at what IA wrote inside the loop construct vis a vis the above.
But, as a general rule, in Matlab don't use loops to do what can be done easily(*) with vectorized operations.
() There are times loops just work out best owing to either there just not being a way to vectorize some operations or that the application of *arrrayfun or other techniques leads to far more complex code and may even perform more slowly or require more memory. But, the first thought should be "how can I use the features of Matlab efficiently?"
Image Analyst
Image Analyst 2016-8-14
It's good to set intermediate variables and check their value with the debugger.
m = max(num_matrix,[],2)
condition = (num_matrix(i,j) == m)
if condition
Now you'll see that m is a column vector - multiple values, not just one. And therefore condition is also a column vector. So "if condition" gives a multitude of things to test, it's not just comparing the current element to a single value. But when that happens, the help says "An expression is true when its result is nonempty and contains only nonzero elements (logical or real numeric). " So in order for that to ever be true, ALL of the elements would have had to be true. But they're not all true (unless the entire matrix had the same max value in every row which is unlikely). So the condition is false and it never gets executed.
dpb and I agree that there are times to use more efficient code like vectorization and special functions like arrayfun() and cellfun().
And I think we also agree that there are times where such code can lead to cryptic (though compact) code that is hard to understand and maintain, and it could be better to use simpler and more intuitive code that is far easier to understand. It's very common that beginners will prefer a simple for loop or while loop over tricky functions like regexp(), cellfun(), arrayfun(), mat2cell(), or whatever. And, as someone who frequently has to look over or adopt other people's code, there is something to be said for clarity and understandability. On that note, I also recommend you use lots of comments and descriptive variable names, even if they're longer, since no one wants to look over a complete alphabet soup mess of uncommented code.
When you're dealing with arrays that are less than a few million elements, often times the speed increase with using a special function or vectorization is very small - not noticeable. So if a for loop takes 0.005 seconds instead of 0.001 seconds (5 times longer than vectorization), maybe the speed up is not as important to you as having easy-to-understand code.
And for loops have gotten a bad rap that has remained even since they "fixed" the speed problem several years ago. They're vastly faster now. Look at this:
tic;
for k = 1 : 1e6
a = 1;
end
toc
Elapsed time is 0.003458 seconds.
So I did a hundred million iterations (that's a lot! ) of a for loop and it only took 3 milliseconds. It's often not the for loop itself that is slower but what you're doing inside it and how much memory you're accessing (for example does it have to go out to virtual memory to fetch data or is it already in the cache).

请先登录,再进行评论。

更多回答(2 个)

Azzi Abdelmalek
Azzi Abdelmalek 2016-8-14
A=randi(100,4,5)
m=max(A,[],2)
A(bsxfun(@eq,A,m))=-1

dpb
dpb 2016-8-14
>> x=randi(20,4)
x =
15 19 15 14
6 9 14 4
9 20 11 3
11 7 14 20
>> [~,ix]=max(x,[],2);
>> x(sub2ind(size(x),[1:4].',ix))=-1
x =
15 -1 15 14
6 9 -1 4
9 -1 11 3
11 7 14 -1
>>

类别

Help CenterFile Exchange 中查找有关 Logical 的更多信息

产品

Community Treasure Hunt

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

Start Hunting!

Translated by