¿Hay una manera fácil de dividir cada elemento de la matriz por la suma de la columna? Por ejemplo:¿Cómo se dividen los elementos de la matriz por sumas de columna en MATLAB?
input:
1 4
4 10
output:
1/5 4/14
4/5 10/14
¿Hay una manera fácil de dividir cada elemento de la matriz por la suma de la columna? Por ejemplo:¿Cómo se dividen los elementos de la matriz por sumas de columna en MATLAB?
input:
1 4
4 10
output:
1/5 4/14
4/5 10/14
He aquí una lista de las diferentes maneras de hacer esto ...
... usando bsxfun
:
B = bsxfun(@rdivide,A,sum(A));
... usando repmat
:
B = A./repmat(sum(A),size(A,1),1);
... usando un outer product (según lo sugerido por Amro):
B = A./(ones(size(A,1),1)*sum(A));
... y utilizando un bucle (como se sugiere en mtrw):
B = A;
columnSums = sum(B);
for i = 1:numel(columnSums)
B(:,i) = B(:,i)./columnSums(i);
end
Actualización:
A partir de MATLAB R2016b y posterior, la mayoría de las funciones binarias incorporadas (lista puede ser f here) admiten la expansión implícita, lo que significa que tienen el comportamiento de bsxfun
de forma predeterminada. Así, en las nuevas versiones de MATLAB, todo lo que tiene que hacer es:
B = A./sum(A);
No se pudo resistir a probar una lista por comprensión. Si esta matriz se representa en una lista por filas de las listas, intente esto:
>>> A = [[1,4],[4,10]]
>>> [[float(i)/j for i,j in zip(a,map(sum,zip(*A)))] for a in A]
[[0.20000000000000001, 0.2857142857142857], [0.80000000000000004, 0.7142857142857143]]
sí, ya sé que esto no es super-eficiente, ya que calculamos las sumas de las columnas una vez por fila. Ahorro de esto en una variable llamada colsums parece:
>>> colsums = map(sum,zip(*A))
>>> [[float(i)/j for i,j in zip(a,colsums)] for a in A]
[[0.20000000000000001, 0.2857142857142857], [0.80000000000000004, 0.7142857142857143]]
Tenga en cuenta que la cremallera (* A) da transponer (A).
a=[1 4;4 10]
a =
1 4
4 10
a*diag(1./sum(a,1))
ans =
0.2000 0.2857
0.8000 0.7143
+1, me gusta este. Lástima que es 20 veces más lento que 'bsxfun'. –
¿No puede tirar el lazo solo para completarlo? :) – mtrw
@mtrw: Sí, sí puedo. ;) – gnovice
puede agregar esto a la lista: 'B = A ./ (unos (tamaño (A, 1), 1) * suma (A, 1))'. Creo que es más rápido que * repmat * pero más lento que * bsxfun * – Amro