C'è un modo semplice per dividere ciascun elemento della matrice per la somma della colonna? Per esempio:Come divido gli elementi matrice per le somme delle colonne in MATLAB?
input:
1 4
4 10
output:
1/5 4/14
4/5 10/14
C'è un modo semplice per dividere ciascun elemento della matrice per la somma della colonna? Per esempio:Come divido gli elementi matrice per le somme delle colonne in MATLAB?
input:
1 4
4 10
output:
1/5 4/14
4/5 10/14
Ecco un elenco dei diversi modi per farlo ...
... usando bsxfun
:
B = bsxfun(@rdivide,A,sum(A));
... usando repmat
:
B = A./repmat(sum(A),size(A,1),1);
... utilizzando un outer product (come suggerito da Amro):
B = A./(ones(size(A,1),1)*sum(A));
... e utilizzando un ciclo for (come suggerito da mtrw):
B = A;
columnSums = sum(B);
for i = 1:numel(columnSums)
B(:,i) = B(:,i)./columnSums(i);
end
Aggiornamento:
A partire da MATLAB R2016b e versioni successive, la maggior parte delle funzioni binarie incorporate (elenco può essere f ound here) supportano l'espansione implicita, ovvero hanno il comportamento di bsxfun
per impostazione predefinita. Quindi, nelle versioni più recenti di MATLAB, tutto ciò che dovete fare è:
B = A./sum(A);
Impossibile resistere alla comprensione di una lista. Se questa matrice è stata rappresentata in un elenco row-major di liste, provate questo:
>>> 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ì, lo so che questo non è super-efficiente, come calcoliamo le somme delle colonne volta per ogni riga. Il salvataggio in una variabile denominata colsums è simile a:
>>> 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]]
Si noti che lo zip (* A) fornisce la trasposizione (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, mi piace questo. Peccato che sia 20 volte più lento di 'bsxfun'. –
Non puoi lanciare il ciclo solo per completezza? :) – mtrw
@mtrw: Sì, sì, posso. ;) – gnovice
è possibile aggiungerlo all'elenco: 'B = A ./ (uno (dimensione (A, 1), 1) * somma (A, 1))'. Penso che sia più veloce di * repmat * ma più lento di * bsxfun * – Amro