I vicini vicini significano calcoloCiao a tutti,
Devo calcolare la media delle matrici/componenti vicini su un wafer microelettronico, ad esempio su una scatola 3x3 come questa:

Il componente di riferimento è al centro di una scatola e quindi circondato da 8 componenti di cui voglio calcolare la media, per ogni riga della tabella dati (calcola poi la stessa cosa per una scatola 5x5 e 16 vicini...)
Sarà utilizzato come una nuova funzionalità per l'apprendimento automatico.
Il mio codice è:
dt = current data table();
<BR />// building the KD table
matrice = (dt:row << getvalues) || (dt:col << getvalues);
table = KDTable(matrice);
for( i=1, i<=nrows(dt),i++,
// get the 3x3 neighbors
neighbors = table << Knearestrows(8,i);
neighbors_number = neighbors[1,1];
// Select the neighbors and get their metrics values and calculate the mean<BR /> dt << select rows (neighbors_number );
mean_selection = Col Mean( If( Selected(), :metric, . ) );
:mean_metric[i] = mean_selection;
dt << clear select
);Qualcuno ha un modo intelligente per eseguire quel calcolo in modo più efficiente?
Grazie!
ScriptingRe: I vicini vicini significano calcoloGrazie per tutto questo, ho intenzione di scavare più a fondo
Re: I vicini vicini significano calcoloCIAO @Franck_R ,
Forse anche questo può aiutarti: Componente aggiuntivo: analisi dei dati spaziali
Se quello che stai cercando è la correlazione spaziale, l'io di Moran è forse il concetto più basilare.
Ron
Re: I vicini vicini significano calcoloPotresti riempire abbastanza righe e colonne di valori mancanti, a sinistra, a destra, in alto, in basso.A seconda di quanto lontano vai con l'estensione del quartiere, potresti avere 8 wafer di valore mancante completi che circondano il vero wafer.
C'è un altro modo per farlo, richiedendo anche righe e colonne fittizie, che saranno molto veloci:
Le matrici JMP 2D possono essere indicizzate come matrici lineari 1D.
[ 1 2,
3 4,
5 6 ] (3 righe, 2 colonne)
sembra anche
[1,
2,
3,
4,
5,
6] (6 righe, 1 colonna quando si utilizza un pedice)
Se il wafer è NRows x NCols, mettilo nel mezzo di una matrice 3NRows x 3NCols (la chiamerò M3).
Puoi creare una matrice di pedici 1D per indicizzare M3 aggiungendo 1 per spostarti orizzontalmente e aggiungendo 3NCols per spostarti verticalmente. Per estrarre una sottomatrice 3x3 da M3, utilizzare la matrice indice e la funzione shape().
qualcosa come questo:
M3 = [. . . . . . . . .,
. . . . . . . . .,
. . . . . . . . .,
. . . 1 2 3 . . .,
. . . 4 5 6 . . .,
. . . 7 8 9 . . .,
. . . . . . . . .,
. . . . . . . . .,
. . . . . . . . .];
indexer2x2 = [1 2 10 11]; // top left 2x2 sub-matrix
For( x = 2, x <= 5, x += 1,
For( y = 2, y <= 5, y += 1,
Write( "\!n ", x, " ", y, " ", Shape( M3[indexer2x2 + x + y * 9], 2 ) );
)
);
2 2 [. ., . 1]
2 3 [. 1, . 4]
2 4 [. 4, . 7]
2 5 [. 7, . .]
3 2 [. ., 1 2]
3 3 [1 2, 4 5]
3 4 [4 5, 7 8]
3 5 [7 8, . .]
4 2 [. ., 2 3]
4 3 [2 3, 5 6]
4 4 [5 6, 8 9]
4 5 [8 9, . .]
5 2 [. ., 3 .]
5 3 [3., 6.]
5 4 [6., 9.]
5 5 [9 ., . .]
Potresti aver bisogno anche di questo: Utilizzo di Loc con una matrice 2D
Puoi creare indexer3x3, ecc. E riutilizzare semplicemente M3 per ogni livello. il ciclo for x=3, x<=5 deve andare un po' oltre ogni volta.
modifica: la funzione shape potrebbe non essere necessaria se stai solo ottenendo la media degli elementi indicizzati, ma aiuta a mostrare cosa è successo sopra. more: le matrici JSL hanno un comportamento speciale quando l'indice è inferiore a 1 e non riceverai il messaggio di errore che potresti sperare! se l'indicizzatore contiene uno zero (o -1 ecc.) sembrerà molto strano.
Re: I vicini vicini significano calcolod'altra parte mi rendo conto che la soluzione del raggio limite non è perfetta perché prendiamo ancora un elemento in più nell'array
ad esempio un raggio di 1.5 contiene un valore di 2 perché questo è il valore che interrompe la ricerca dei vicini... Quindi non mi dà esattamente quello che voglio, dovrò cercare ancora un po'!
Re: I vicini vicini significano calcoloGrazie mille è molto interessante!
A volte uso "inizia l'aggiornamento dei dati" ma non ci ho pensato qui: buon punto. Con ciò, la soluzione Loc() è in realtà un po' più lenta di knearestrows() se aggiungi l'aggiornamento iniziale che trovo per 20.000 righe:
vecchio script senza aggiornamento iniziale: 116s!
knearestrows() con inizio aggiornamento: 5s
Loc() con inizio aggiornamento: 14s
ma per i knearestrows ho dovuto cambiare il modo in cui calcolo la media poiché non possiamo più utilizzare le righe selezionate con l'aggiornamento di inizio/fine.
Per i bordi hai perfettamente ragione, avevo pensato di inserire:
neighbors = table << Knearestrows( {8, 1.5}, i );
Per evitare questo problema si utilizza un raggio limitato
Grazie ancora!
Re: I vicini vicini significano calcoloSono abbastanza sicuro che la dimensione del problema determinerà se l'approccio kdtable() o loc() è migliore. Immagino che loc() vincerà per una matrice 10x10 o più piccola e kdtable per 100x100 o più grande.
Il punto di Xan sui bordi è importante. Loc() potrebbe essere il modo più semplice per ottenere la risposta giusta.
Ri: I vicini vicini significano calcoloNon sono sicuro di come si confronti l'efficienza, ma ecco un'alternativa da provare.
- L'utilizzo di start/end data update() aiuterà per qualsiasi metodo
- L'utilizzo di Nearest Neighbor è intelligente (e forse anche più efficiente) ma tieni presente che restituirà sempre l'8 più vicino, anche ai bordi del wafer dove i vicini saranno tutti su un lato.
- L'indice di matrice può essere più efficiente di Col Mean().
dt = current data table();
metrics = dt[0, "metric"];
rows = dt[0, "row"];
cols = dt[0, "col"];
d = 1; // 1 => 3x3, 2 => 5x5
dt << Begin Data Update();
For Each Row(
neighbors = Loc( :col - d <= cols <= :col + d & :row - d <= rows <= :row + d );
mean all = Mean( metrics[neighbors] );
nn = N Rows( neighbors );
mean without center = (mean all * nn - :metric) / (nn - 1);
:mm = mean without center;
);
dt << End Data Update();