2009-11-20 4 views

risposta

41

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); 
+2

Non puoi lanciare il ciclo solo per completezza? :) – mtrw

+0

@mtrw: Sì, sì, posso. ;) – gnovice

+2

è 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

0

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).

+2

È quel Python? – gnovice

+0

Oh, mi dispiace, si lo è. Non ho notato il tag Matlab. – PaulMcG

1
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 
+0

+1, mi piace questo. Peccato che sia 20 volte più lento di 'bsxfun'. –