Loc 反函數大家好。我為特定任務製作了此 JSL 函數,但我想知道是否有更好的方法來執行此操作。
我想要的是一種方法,如果您有一個索引向量,則創建指定鏈接的指示向量,其中向量元素的值對於指定索引為 1,否則為 0。例如
[2, 3, 6] --> 轉換為長度為 10 的指示向量。
[0, 1, 1, 0, 0, 0, 1, 0, 0, 0]
用例是根據多個條件在數據表中選擇行的子集,對於每個條件,我得到一個滿足條件的行號向量,我想得到滿足所有條件的行。
// 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;
);
因此,對於用例,例如,如果我有三個條件,我會得到滿足每個條件(v1、v2、v3)的向量中的行號,所以我會這樣做
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);回复:Loc 反函數我認為你的方法很好。 如果您有許多或未知數量的子句和/或許多行,您可以嘗試使用此函數,它接受行號矩陣列表:
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)))
);
這裡的主要好處是只需要創建和存儲一個全尺寸數組。 下面是一個比較超過一百萬行的 6 個子句的運行時間的示例。
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)"));

回复:Loc 反函數雖然我可能會誤解這個問題,Associative Array 可以得到兩個集合的交集。
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>回复:Loc 反函數你好佑介山,
感謝您將關聯數組帶入討論。 正如您提到的,<
作為示例,下面我包含代碼和日誌輸出,以使用 30K 行乘 9 列樣本數據集比較每種方法。 在這種情況下,關聯數組方法的運行時間大約是矩陣方法的 65 倍。
乾杯,
布雷迪
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^." ) );

回复:Loc 反函數非常感謝,布雷迪桑
我也嘗試 For Each 如下所示,但您的矩陣方法仍然更快。 我瘋狂地猜測從向量創建關聯數組需要很多時間。
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();