Fonction Loc inverseSalut tout le monde.J'ai créé cette fonction JSL pour une tâche spécifique, mais je me demandais s'il existait un meilleur moyen de le faire.
Ce que je veux, c'est un moyen, si vous avez un vecteur d'indices, de créer un vecteur indicateur d'un lien spécifié où la valeur de l'élément vectoriel est 1 pour l'indice spécifié et 0 sinon.PAR EXEMPLE
[2, 3, 6] --> convertir en vecteur indicateur de longueur 10.
[0, 1, 1, 0, 0, 0, 1, 0, 0, 0]
Le cas d'utilisation consiste à sélectionner des sous-ensembles de lignes dans une table de données en fonction de plusieurs conditions, où pour chaque condition, j'obtiens un vecteur des numéros de lignes qui remplissent la condition, et je veux obtenir les lignes qui remplissent toutes les conditions.
// 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;
);
Donc, pour le cas d'utilisation, par exemple, si j'ai trois conditions, j'obtiens les numéros de ligne dans les vecteurs qui remplissent chaque condition (v1, v2, v3), donc je ferais ceci
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);Re: Fonction Loc InverseJe pense que ta démarche est bonne. Si vous avez de nombreuses clauses, ou un nombre inconnu, et/ou de nombreuses lignes, vous pouvez expérimenter cette fonction, qui accepte une liste de matrices de numéros de lignes :
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)))
);
Le principal gain ici est qu'un seul tableau complet doit être créé et stocké. Vous trouverez ci-dessous un exemple qui compare les durées d'exécution de 6 clauses sur un million de lignes.
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)"));

Re: Fonction Loc InverseBien que je puisse mal comprendre la question, Associative Array peut obtenir l'ensemble d'intersection de deux ensembles.
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>Re: Fonction Loc InverseBonjour Yusuke-san,
Merci d'avoir introduit les tableaux associatifs dans la discussion. Comme vous le mentionnez, <
À titre d'exemple, j'inclus ci-dessous le code et la sortie du journal pour comparer chaque méthode à l'aide de votre ensemble de données d'échantillons de 30 000 lignes sur 9 colonnes. Dans ce cas, la méthode de tableau associatif prend environ 65 fois plus de temps à s'exécuter que la méthode matricielle.
À votre santé,
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^." ) );

Re: Fonction Loc InverseMerci beaucoup, Brady-san
J'essaie également For Each comme ci-dessous, mais votre méthode matricielle est toujours plus rapide. Je suppose qu'il faut beaucoup de temps pour créer des tableaux associatifs à partir de vecteurs.
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();