accumarray
utilizza due file di indici per creare una matrice con elementi sulla posizione delle coppie di indice validi con un valore assegnato dalla funzione specificata, ad esempio:Lasciando accumarray uscita un tavolo
A = [11:20];
B = flipud([11:20]);
C = 1:10;
datamatrix = accumarray([A B],C);
questo modo datamatrix
sarà una matrice 20x20
con valori. Se i valori di A
e B
tuttavia sono molto grandi, questo si tradurrà in una matrice per lo più vuota, con una piccola serie di dati nell'angolo più lontano. Per aggirare questo, si potrebbe impostare accumarray
a issparse
:
sparsedatamatrix = accumarray([A B],C,[],@sum,[],true);
Questo farà risparmiare un sacco di memoria in caso min(A)
e/o min(B)
è/sono molto grandi.
mio problema, tuttavia, è che ho una matrice Mx7
, con M~1e8
, su cui voglio raccogliere i mezzi di colonne tre a sette sulla base indicizzazione nelle prime due colonne e la deviazione standard della terza colonna basata sul terzo così:
result = accumarray([data(:,1) data(:,2)],data(:,3),[],@std);
voglio salvare questo ritorno in una tabella, strutturato come [X Y Z std R G B I]
, dove X
e Y
sono gli indici, Z
è l'altezza media di quel pixel, R
, G
, B
e I
sono valori medi (colore e intensità) per pixel e std
è la deviazione standard delle altezze (ad es. la ruvidità). L'utilizzo di issparse
in questo caso non aiuta, poiché trasformo le matrici risultanti da accumarray
utilizzando repmat
.
Il punto di questo codice è di stimare l'altezza, la rugosità, il colore e l'intensità di un pezzo di terra da una nuvola di punti. Ho arrotondato le coordinate in X e Y per creare una griglia e ora ho bisogno di quei valori medi per cella della griglia, ma ho l'output come una "tabella" (non il tipo di dati MATLAB, ma un array 2D che non è l'output matrice predefinito).
Quindi, per concludere con la domanda:
C'è un modo per accumarray
o una funzione simile a questa tabella di uscita senza (potenzialmente molto grande) matrice intermedia?
codice qui sotto:
Xmax = max(Originaldata(:,1));
Ymax = max(Originaldata(:,2));
X_avg_grid=(Edgelength:Edgelength:Xmax*Edgelength)+Xorig;
TestSet = zeros(Xmax*Ymax,9);
xx = [1:length(X_avg_grid)]'; %#ok<*NBRAK>
TestSet(:,1) = repmat(xx,Ymax,1);
ll = 0:Xmax:Xmax*Ymax;
for jj = 1:Ymax
TestSet(ll(jj)+1:ll(jj+1),2) = jj;
end
for ll = 1:7
if ll == 2
tempdat = accumarray([Originaldata(:,1) Originaldata(:,2)],Originaldata(:,3),[],@std);
tempdat = reshape(tempdat,[],1);
TestSet(:,ll+2) = tempdat;
elseif ll == 7
tempdat = accumarray([Originaldata(:,1) Originaldata(:,2)],1);
tempdat = reshape(tempdat,[],1);
TestSet(:,ll+2) = tempdat;
elseif ll == 1
tempdat = accumarray([Originaldata(:,1) Originaldata(:,2)],Originaldata(:,3),[],@mean);
tempdat = reshape(tempdat,[],1);
TestSet(:,ll+2) = tempdat;
else
tempdat = accumarray([Originaldata(:,1) Originaldata(:,2)],Originaldata(:,ll+1),[],@mean);
tempdat = reshape(tempdat,[],1);
TestSet(:,ll+2) = tempdat;
end
end
TestSet = TestSet(~(TestSet(:,9)==0),:);
nona colonna qui è solo la quantità di punti per cellula.
Originaldata =
19 36 2.20500360107422 31488 31488 31488 31611
20 37 2.26400360107422 33792 33792 34304 33924
20 37 2.20000360107422 33536 33536 34048 33667
19 36 2.20500360107422 34560 34560 34560 34695
20 36 2.23300360107422 32512 32512 33024 32639
21 38 2.22000360107422 31744 31488 33024 31611
21 37 2.20400360107422 32512 32768 33792 32896
21 37 2.24800360107422 29696 29440 30720 29555
21 38 2.34800360107422 32768 32768 32768 32639
21 37 2.23000360107422 33024 33024 33536 33153
Quindi tutti i punti della stessa X, Y (ad esempio [19 36]
o [21 37]
) sono mediati (altezza, RGB, intensità in questo ordine) e dei valori nella terza colonna della deviazione standard è anche desiderata:
Result =
19 36 2.2050036 0.00 33024 33024 33024 33153
21 37 2.227336934 0.02212088 31744 31744 32682.66 31868
e così via per il resto dei dati.
Ho aggiornato il mio codice all'ultima versione che ho. Questa memoria ridotta in testa un po ', poiché ora la funzione crea le griglie una dopo l'altra anziché tutte in una volta. Tuttavia, il codice è in esecuzione in parallelo, quindi ci sono ancora otto griglie simultanee create, quindi una soluzione sarebbe comunque apprezzata.
Non sono sicuro di seguirlo. Se vuoi fare come 'accumarray' fa solo sommare _rows_ invece di numeri, puoi usare (sparse) la moltiplicazione della matrice come in [questo Q & A] (http://stackoverflow.com/questions/29906059/summing-rows-by- index-using-accumarray) –
Non posso usare sparse() poiché non supporta altre funzioni oltre alla sua "somma" nativa e non può fare accumarray fuori da una matrice sparsa, dal momento che repmat non può funzionare con gli spars. – Adriaan
Ho la sensazione che ciò che si desidera _can_ venga eseguito con una moltiplicazione di matrice sparsa. Ma dovresti creare un esempio minimo e funzionante con input e output desiderati; la tua domanda così com'è non è molto chiara –