Нормализация строки разреженной матрицы в нулевое среднее значение в 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, но не сделал этого.

У кого-нибудь есть векторизованное решение?


person Jia    schedule 13.09.2012    source источник


Ответы (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.

spy(B)

spyplot.jpg

person Community    schedule 13.09.2012
comment
[i, j.a] = найти (A); должно быть [i,j,a] = find(A); я прав? - person Eugenio; 03.12.2014