Loc UmkehrfunktionHallo zusammen.Ich habe diese JSL-Funktion für eine bestimmte Aufgabe erstellt, aber ich habe mich gefragt, ob es einen besseren Weg gibt, dies zu tun.
Was ich möchte, ist eine Möglichkeit, wenn Sie einen Vektor von Indizes haben, einen Indikatorvektor eines angegebenen Links zu erstellen, wobei der Wert des Vektorelements für den angegebenen Index 1 und andernfalls 0 ist.Z.B
[2, 3, 6] --> in Indikatorvektor der Länge 10 umwandeln.
[0, 1, 1, 0, 0, 0, 1, 0, 0, 0]
Der Anwendungsfall besteht darin, Teilmengen von Zeilen in einer Datentabelle basierend auf mehreren Bedingungen auszuwählen, wobei ich für jede Bedingung einen Vektor der Zeilennummern erhalte, die die Bedingung erfüllen, und ich möchte die Zeilen erhalten, die alle Bedingungen erfüllen.
// 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;
);
Wenn ich beispielsweise drei Bedingungen habe, erhalte ich für den Anwendungsfall die Zeilennummern in Vektoren, die jede Bedingung erfüllen (v1, v2, v3), also würde ich dies tun
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);Betreff: Loc UmkehrfunktionIch finde deinen Ansatz gut. Wenn Sie viele oder eine unbekannte Anzahl von Klauseln und/oder viele Zeilen haben, können Sie mit dieser Funktion experimentieren, die eine Liste von Matrizen von Zeilennummern akzeptiert:
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)))
);
Der Hauptvorteil besteht darin, dass nur ein einziges Array voller Größe erstellt und gespeichert werden muss. Unten sehen Sie ein Beispiel, das Laufzeiten für 6 Klauseln über eine Million Zeilen vergleicht.
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)"));

Betreff: Loc UmkehrfunktionObwohl ich die Frage möglicherweise falsch verstehe, kann Associative Array die Schnittmenge von zwei Mengen erhalten.
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>Betreff: Loc UmkehrfunktionHallo Yusuke-san,
Vielen Dank, dass Sie assoziative Arrays in die Diskussion eingebracht haben. Wie Sie bereits erwähnt haben, ist <
Als Beispiel füge ich unten Code- und Protokollausgaben hinzu, um jede Methode mit Ihrem Beispieldatensatz von 30.000 Zeilen und 9 Spalten zu vergleichen. In diesem Fall dauert die Ausführung der assoziativen Array-Methode etwa 65-mal so lange wie die Matrix-Methode.
Prost,
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^." ) );

Betreff: Loc UmkehrfunktionVielen Dank, Mr. Brady
Ich versuche es auch mit For Each wie unten, aber Ihre Matrixmethode ist immer noch schneller. Ich vermute wild, dass es viel Zeit in Anspruch nimmt, assoziative Arrays aus Vektoren zu erstellen.
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();