Avoiding loops, is there a way to center a matrix of data around the mean of the columns (or rows), scaling each entry by the standard deviation (also column-wise or row-wise)?
In R this is easy: scale(data, center = T, scale = T))
.
But I don't know how to achieve the same basic pre-processing in Ocatave or Matlab.
In Octave, you have two functions for this center() and zscore(). center just subtracts the mean, whereas zscore also divides by sd (an operation sometimes known as known as standarization)
center (x)
Center data by subtracting its mean.
If x is a vector, subtract its mean. If x is a matrix, do the above for each column. If the optional argument dim is given, operate along this dimension.
and
zscore (x, opt, dim) Computes the Z score of x
if x is a vector, subtract its mean and divide by its standard deviation. If the standard deviation is zero, divide by 1 instead.
The optional parameter opt determines the normalization to use when computing the standard deviation and has the same definition as the corresponding parameter for std.
If x is a matrix, calculate along the first non-singleton dimension. If the third optional argument dim is given, operate along this dimension.
There isn't a single function that does this but you can use the dim
parameter for std
and mean
to accomplish this. We can also use bsxfun
to wrap it all into one line.
A = rand(5, 4);
% Column-wise
bsxfun(@rdivide, bsxfun(@minus, A, mean(A, 1)), std(A, [], 1))
% Row-wise
bsxfun(@rdivide, bsxfun(@minus, A, mean(A, 2)), std(A, [], 2))
Explanation
Using the dim
parameter to mean
we can compute the mean value for each column of A
.
M = mean(A, 1)
Then we can use bsxfun
to subtract the mean from each value in each column ( @minus
). We need to use bsxfun
because M
is 1 x nCols
and A
is nRows x nCols
. bsxfun
will automatically broadcast the operation for us.
B = bsxfun(@minus, A, M);
Then we want to compute the standard deviation of each column, again using the dim
parameter (third input).
S = std(A, [], 1)
And divide each column by this standard deviation
bsxfun(@rdivide, B, S);
So bringing this all together we get
bsxfun(@rdivide, bsxfun(@minus, A, mean(A, 1)), std(A, [], 1))
To perform the row-wise operation, all we need to do is switch the dim
parameter from 1 (columns) to 2 (rows).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.