Gente
He estado trabajando bastante tiempo en scripts de unión no estándar, y parece que tendré que hacerlo mucho.
En este punto necesito unir dos tablas.
El primero tiene series de medidas en diferentes herramientas. Las mediciones se realizan en sesiones. Pero la tabla solo tiene lo siguiente: herramienta, evento, resultado .
La segunda tabla tiene toda la información sobre las sesiones:
herramienta, sessionid, starttime, endtime
Y necesito hacer un análisis de medidas por ID de sesión
Básicamente, necesito unirme único ID de sesión a cada linea en la primera tabla.
La forma en que lo hago actualmente es iterar a través de cada línea en la primera tabla y buscar la línea correspondiente en la segunda tabla donde herramienta es emparejado y hora del evento está en el medio hora de inicio y hora de finalización usando esto:
currentStartEndInfoindex=dt2 << Get Rows Where(:tool==thisTool & :measstart < thisEventtime & :measend > thisEventtime);
dónde esta herramienta y thisEventtime son la herramienta y el tiempo de la primera tabla que estoy recorriendo. Me sale indeces de la lista con los únicos. ID de sesión a partir de la segunda tabla que coincida con esta condición y luego compile una lista de ellos que al final del bucle se utiliza para rellenar la nueva columna en la primera tabla. Esta línea "Obtener filas donde" toma el 85% del tiempo de ejecución del script.
Ahora, con unos pocos millones de líneas en la primera tabla y cientos de miles en la segunda tabla, toma entre 8 y 16 horas.
No puedo permitirme correr tanto tiempo.
Por lo tanto, pregunta:
¿Hay alguna forma de optimizar eso? Después de todo, para cada línea en la primera tabla, mira la segunda tabla una y otra vez, no muy eficiente.
Una idea que tengo es dividir la segunda tabla en sublistas por herramienta y luego hacer "Obtener filas donde" para cada línea en sublista que corresponda a esa herramienta específica. Sin embargo, no tengo idea de cómo implementarlo mejor.
Cualquier ayuda sería muy apreciada.
¡Gracias!
Aquí hay una primera aproximación
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>
Funciona, pero aún es demasiado lento, es posible que desee aprovechar la clasificación de la tabla de "eventos" por eventTime y reemplazar el loc () con una búsqueda binaria.