Строка-нормализует разреженную матрицу в нулевое среднее в Matlab
У меня есть большая m *n разреженная матрица Y. Я хотел бы нормализовать каждую строку Y, чтобы каждая строка имела нулевое среднее значение.
Я впервые попробовал это. Но среднее значение каждой строки также вычитается из нулевых записей, а это не то, что я хочу.
Ynorm = bsxfun(@minus, Y, Ymean);
Тогда я попробовал это.
[m, n] = size(Y);
nonZeroNum = nnz(Y);
Ynorm = spalloc(m,n,nonZeroNum);
for i = 1:m
Ynorm(i, :) = spfun(@(x)(x - Ymean(i)), Y(i, :));
end
Однако это не векторизованное решение слишком медленное.
Я также думал о комбинировании bsxfun и spfun, но не смог.
У кого-нибудь есть векторизованное решение?
1 ответ
Очень просто.
Случайная разреженная матрица.
A = sprand(100,100,.05);
Грести значит. Если в строке нет ненулевых элементов, мы ожидаем, что 0/0 = NaN, но следующий шаг никогда не затронет эту строку.
rowmeans = sum(A,2)./sum(A~=0,2);
Извлечь ненулевые.
[i,j.a] = find(A);
И восстановить массив, значит вычесть.
[n,m] = size(A);
B = sparse(i,j,a - rowmeans(i),n,m);
Теперь проверь это. Не забывайте, что здесь применяется арифметика с плавающей запятой, поэтому значение строки не будет точно нулевым, только порядка eps.
min(mean(B,2))
ans =
(1,1) -1.5543e-17
max(mean(B,2))
ans =
(1,1) 1.1657e-17
Кажется, правильно и полностью векторизовано. Чтобы убедить вас, что результат действительно скудный и нулевые элементы не были повреждены, вот результат шпиона.
spy(B)