Loc Funzione inversaCiao a tutti.Ho creato questa funzione JSL per un'attività specifica, ma mi chiedevo se esiste un modo migliore per farlo.
Quello che voglio è un modo è se hai un vettore di indici, per creare un vettore indicatore di un collegamento specificato in cui il valore dell'elemento vettoriale è 1 per l'indice specificato e 0 altrimenti.PER ESEMPIO
[2, 3, 6] --> converti in vettore indicatore di lunghezza 10.
[0, 1, 1, 0, 0, 0, 1, 0, 0, 0]
Il caso d'uso è per selezionare sottoinsiemi di righe in una tabella di dati basata su più condizioni, dove per ogni condizione ottengo un vettore dei numeri di riga che soddisfano la condizione e voglio ottenere le righe che soddisfano tutte le condizioni.
// Loc Inverse Function
// This function converts a vector of positive integers (locvals) into an
// indicator vector of a specified length, n, with the values
// v[I] = 1 if I is in locvals, and 0 otherwise
// example
// Loc Inverse(6, [1,3])
// returns
// [1, 0, 1, 0, 0, 0]
*/
Loc Inverse = Function( {n, locvals},
v = J( n, 1, 0 );
v[locvals] = 1;
v;
);
Quindi, per il caso d'uso, ad esempio, se ho tre condizioni, ottengo i numeri di riga nei vettori che soddisfano ciascuna condizione (v1, v2, v3), quindi lo farei
dt=current data table();
Loc Inverse = Function( {n, locvals},
v = J( n, 1, 0 );
v[locvals] = 1;
v;
);
// ...
// code to get v1, v2, v3
// ...
rowindicator1=Loc Inverse(n rows(dt), v1);
rowindicator2=Loc Inverse(n rows(dt), v2);
rowindicator3=Loc Inverse(n rows(dt), v3);
meet_all_conditions_indicator = rowindicator1 & rowindicator2 & rowindicator3;
rows_that_meet_all_conditions = Loc(meet_all_conditions_indicator);Ri: Loc Funzione inversaPenso che il tuo approccio vada bene. Se hai molte o un numero sconosciuto di clausole e/o molte righe, potresti sperimentare questa funzione, che accetta un elenco di matrici di numeri di riga:
common = function({nr, vList},
{default local},
mat = J(nr, 1, 0);
for each( {i}, 1::nitems(vList), mat[vlist[i]]++ );
return(loc(mat, nitems(vList)))
);
Il vantaggio principale qui è che deve essere creato e memorizzato solo un singolo array a grandezza naturale. Di seguito è riportato un esempio che confronta i tempi di esecuzione per 6 clausole su un milione di righe.
names default to here(1);
nr = 1e6;
p = 0.6;
nClause = 6;
//create a list of vectors, each representing the rows returned from a given clause.
//rows are selected with probability p within any clause
vecLis = {};
for each( {i}, 1::nClause, insertinto(vecLis, loc(J(nr,1, randombinomial(1,p)))));
Loc Inverse = Function( {n, locvals},
v = J( n, 1, 0 );
v[locvals] = 1;
v;
);
common = function({nr, vList},
{default local},
mat = J(nr, 1, 0);
for each( {i}, 1::nitems(vList), mat[vlist[i]]++ );
return(loc(mat, nitems(vList)))
);
t1 = hptime();
rws = common(nr,vecLis);
t2 = hptime();
t3 = hptime();
rowindicator1=Loc Inverse(nr, vecLis[1]);
rowindicator2=Loc Inverse(nr, vecLis[2]);
rowindicator3=Loc Inverse(nr, vecLis[3]);
rowindicator4=Loc Inverse(nr, vecLis[4]);
rowindicator5=Loc Inverse(nr, vecLis[5]);
rowindicator6=Loc Inverse(nr, vecLis[6]);
meet_all_conditions_indicator = rowindicator1 & rowindicator2 & rowindicator3 & rowindicator4 & rowindicator5 & rowindicator6;
rows_that_meet_all_conditions = Loc(meet_all_conditions_indicator);
t4 = hptime();
//Print(evalinsert("Number of Rows: ^nr^.\!NProportion 'Yes' ^p^.\!NNumber of clauses: ^nClause^."));
Print(evalinsert("single matrix approach: ^(t2-t1)/1e6^ secs."));
Print(evalinsert("InvLoc approach: ^(t4-t3)/1e6^ secs."));
Print(evalinsert("Answers differ or are empty: ^try(sum(rws != rows_that_meet_all_conditions), 1)"));

Ri: Loc Funzione inversaAnche se potrei fraintendere la domanda, Associative Array può ottenere l'insieme di intersezione di due insiemi.
Names Default To Here(1);
/* Sample Data */
n = 30000;
p = 9;
vec = J(n, p, .);
For(i = 1, i <= NCol(vec), i++,
vec[0, i] = (1::n)`*i;
);
/* From Here */
a={};
For(i = 1, i<=NCol(vec), i++,
a[i] = Associative Array(vec[0,i]);
);
For(i = 2, i <= N Items(a), i++,
a[1] << Intersect(a[i]); /* Intersection Set (A1 cap A2 cap ... cap Ap)*/
);
answer = a[1] <<GET keys=""></GET>Ri: Loc Funzione inversaCiao Yusuke-san,
Grazie per aver introdotto gli array associativi nella discussione. Come hai detto, <
Ad esempio, di seguito includo il codice e l'output del registro per confrontare ciascun metodo utilizzando il set di dati campione di 30.000 righe per 9 colonne. In questo caso, il metodo dell'array associativo richiede circa 65 volte il tempo di esecuzione del metodo della matrice.
Saluti,
Brady
Names Default To Here( 1 );
/* Sample Data */
n = 30000;
p = 9;
vec = J( n, p, . );
For( i = 1, i <= N Col( vec ), i++,
vec[0, i] = (1 :: n)` * i
);
t1 = HP Time();
a = {};
For( i = 1, i <= N Col( vec ), i++,
a[i] = Associative Array( vec[0, i] )
);
For( i = 2, i <= N Items( a ), i++,
a[1] << Intersect( a[i] ); /* Intersection Set (A1 cap A2 cap ... cap Ap)*/
);
answer = a[1] << Get Keys;
t2 = HP Time();
common = Function( {nr, vList},
{default local},
mat = J( nr, 1, 0 );
For Each( {i}, 1 :: N Items( vList ), mat[vlist[i]]++ );
Return( Loc( mat, N Items( vList ) ) );
);
t3 = HP Time();
vecLis = {};
For Each( {i}, 1 :: N Col( vec ), Insert Into( vecLis, vec[0, i] ) );
nr = Max( vec );
answer2 = common( nr, vecLis );
t4 = HP Time();
Print( Eval Insert( "AAs: ^(t2-t1)/1e6^ secs; ^answer^." ) );
Print( Eval Insert( "matrix: ^(t4-t3)/1e6^ secs; ^answer2^." ) );

Ri: Loc Funzione inversaGrazie mille, Brady-san
Provo anche For Each come sotto, ma il tuo metodo matrix è ancora più veloce. Immagino selvaggiamente che ci voglia molto tempo per creare array associativi dai vettori.
t1 = HP Time();
a = Associative Array(vec[0, 1]);
For Each({i}, 2::N Col(vec),
a << Intersect(Associative Array( vec[0, i] ));
);
answer = a << Get Keys;
t2 = HP Time();