问题
I have a 3D array containing five 3-by-4 slices, defined as follows:
rng(3372061);
M = randi(100,3,4,5);
I'd like to collect some statistics about the array:
- The maximum value in every column.
- The mean value in every row.
- The standard deviation within each slice.
This is quite straightforward using loops,
sz = size(M);
colMax = zeros(1,4,5);
rowMean = zeros(3,1,5);
sliceSTD = zeros(1,1,5);
for indS = 1:sz(3)
sl = M(:,:,indS);
sliceSTD(indS) = std(sl(1:sz(1)*sz(2)));
for indC = 1:sz(1)
rowMean(indC,1,indS) = mean(sl(indC,:));
end
for indR = 1:sz(2)
colMax(1,indR,indS) = max(sl(:,indR));
end
end
But I'm not sure that this is the best way to approach the problem.
A common pattern I noticed in the documentation of max, mean and std is that they allow to specify an additional dim
input. For instance, in max
:
M = max(A,[],dim)
returns the largest elements along dimensiondim
. For example, ifA
is a matrix, thenmax(A,[],2)
is a column vector containing the maximum value of each row.
How can I use this syntax to simplify my code?
回答1:
Many functions in MATLAB allow the specification of a "dimension to operate over" when it matters for the result of the computation (several common examples are: min
, max
, sum
, prod
, mean
, std
, size
, median
, prctile
, bounds
) - which is especially important for multidimensional inputs. When the dim
input is not specified, MATLAB has a way of choosing the dimension on its own, as explained in the documentation; for example in max
:
- If
A
is a vector, thenmax(A)
returns the maximum ofA
.- If
A
is a matrix, thenmax(A)
is a row vector containing the maximum value of each column.- If
A
is a multidimensional array, thenmax(A)
operates along the first array dimension whose size does not equal1
, treating the elements as vectors. The size of this dimension becomes1
while the sizes of all other dimensions remain the same. IfA
is an empty array whose first dimension has zero length, thenmax(A)
returns an empty array with the same size asA
.
Then, using the ...,dim)
syntax we can rewrite the code as follows:
rng(3372061);
M = randi(100,3,4,5);
colMax = max(M,[],1);
rowMean = mean(M,2);
sliceSTD = std(reshape(M,1,[],5),0,2); % we use `reshape` to turn each slice into a vector
This has several advantages:
- The code is easier to understand.
- The code is potentially more robust, being able to handle inputs beyond those it was initially designed for.
- The code is likely faster.
In conclusion: it is always a good idea to read the documentation of functions you're using, and experiment with different syntaxes, so as not to miss similar opportunities to make your code more succinct.
来源:https://stackoverflow.com/questions/49510413/how-to-perform-operations-along-a-certain-dimension-of-an-array