gente,
Ho lavorato molto tempo su script di join non standard, e sembra che avrò bisogno di farlo molto.
A questo punto ho bisogno di unire due tabelle.
Il primo ha una serie di misurazioni su diversi strumenti. Le misurazioni sono fatte in sessioni. Ma la tabella ha solo il seguente: strumento, evento, risultato .
La seconda tabella ha tutte le informazioni sulle sessioni:
strumento, sessionid, ora di inizio, ora di fine
E ho bisogno di fare analisi delle misure di sessionid
Fondamentalmente, ho bisogno di aderire unico sessionid a ogni riga nella prima tabella.
Il modo in cui attualmente lo faccio è di scorrere tutte le righe nella prima tabella e cercare la riga corrispondente nella seconda tabella in cui strumento è abbinato e orario dell'evento è in mezzo orario di inizio e fine del tempo usando questo:
currentStartEndInfoindex=dt2 << Get Rows Where(:tool==thisTool & :measstart < thisEventtime & :measend > thisEventtime);
dove Thistool e thisEventtime sono lo strumento e il tempo del primo tavolo che sto iterando. Ottengo indeces della lista con unico sessionid dalla seconda tabella che corrisponde a questa condizione e quindi assemblare una lista da loro che alla fine del ciclo viene utilizzata per popolare la nuova colonna nella prima tabella. Questa linea "Get Rows Where" richiede l'85% del tempo di esecuzione dello script.
Ora, con qualche milione di righe nella prima tabella e centinaia di migliaia nella seconda tabella, richiede un po 'tra le 8 e le 16 ore.
Non posso permettermi di correre così a lungo.
Pertanto, domanda:
C'è un modo per ottimizzarlo? Dopotutto, per ogni riga nella prima tabella guarda più e più volte attraverso il secondo tavolo - non molto efficiente.
Un'idea che ho è quella di rompere il secondo tavolo in sottoliste per strumento e quindi fare "Ottieni righe dove" per ogni riga su sottolista che corrisponde a quello specifico strumento. Non ho idea di come implementarlo al meglio, però.
Qualsiasi aiuto sarebbe molto apprezzato.
Grazie!
Ecco una prima approssimazione
aaa = New Table( "aaa", // the "event" table
Add Rows( 6 ),
New Column( "tool", Numeric, "Continuous", Format( "Best", 12 ), Set Values( [100, 100, 100, 200, 200, 200] ) ),
New Column( "eventtime", Numeric, "Continuous", Format( "Best", 12 ), Set Values( [11, 21, 12, 31, 41, 42] ) ),
New Column( "result", Numeric, "Continuous", Format( "Best", 12 ), Set Values( [0, 1, 1, 1, 0, 0] ) ),
New Column( "sessionID_added", Numeric, "Continuous", Format( "Best", 12 ), Set Selected, Set Values( [., ., ., ., ., .] ) )
);
bbb = New Table( "bbb", // the start-end table
Add Rows( 4 ),
New Column( "tool", Numeric, "Continuous", Format( "Best", 12 ), Set Values( [100, 100, 200, 200] ) ),
New Column( "sessionID", Numeric, "Continuous", Format( "Best", 12 ), Set Values( [111, 222, 333, 444] ) ),
New Column( "startTime", Numeric, "Continuous", Format( "Best", 12 ), Set Values( [10, 20, 30, 40] ) ),
New Column( "endTime", Numeric, "Continuous", Format( "Best", 12 ), Set Values( [19, 29, 39, 49] ) )
);
// build two lookup tables that find all the rows associated with a tool
aaaRowsFromTool = Associative Array();
For( irow = 1, irow <= N Rows( aaa ), irow++,
If( !(aaaRowsFromTool << Contains( aaa:tool[irow] )), //
aaaRowsFromTool[aaa:tool[irow]] = Eval List( {irow} )//
, //
Insert Into( aaaRowsFromTool[aaa:tool[irow]], irow ) //
)
);
bbbRowsFromTool = Associative Array();
For( irow = 1, irow <= N Rows( bbb ), irow++,
If( !(bbbRowsFromTool << Contains( bbb:tool[irow] )), //
bbbRowsFromTool[bbb:tool[irow]] = Eval List( {irow} )//
, //
Insert Into( bbbRowsFromTool[bbb:tool[irow]], irow ) //
)
);
toolList = bbbRowsFromTool << getkeys;
For( itool = 1, itool <= N Items( toolList ), itool += 1,
toolno = toolList[itool];
// build a sorted list of event times+row numbers for this tool
aaaRowList = aaaRowsFromTool[toolno];
aaa << selectrows( aaaRowList );
aaasub = aaa << Subset( Selected Rows( 1 ), Selected columns only( 0 ), link to original data table( 1 ) );
//aaasub << sort( by( eventTime ), replace table );
timeMatrix = aaasub:eventtime << getAsMatrix;
bbbRowList = bbbRowsFromTool[toolno];
For( irow = 1, irow <= N Items( bbbRowList ), irow += 1,
bbbRow = bbbRowList[irow];
start = bbb:startTime[bbbRow];
end = bbb:endTime[bbbRow];
id = bbb:sessionID[bbbRow];
// find the eventTimes between start and end, for this tool
//aaasub<<SELECTWHERE></SELECTWHERE>
Funziona, ma è troppo lento, potresti voler sfruttare l'ordinamento della tabella "evento" per eventTime e sostituire loc () con una ricerca binaria.