데이터 테이블 대신 행렬로 작업할 때 Lag()의 대안모두,
데이터 테이블 대신 행렬로 작업할 때 사용할 수 있는 lag() 대신 사용할 수 있는 것이 있습니까? 본질적으로, 나는 현재 행의 값을 결정하기 위해 행렬에서 내 열의 이전 행 값을 볼 수 있기를 원합니다. 이는 데이터 테이블의 lag() 함수를 사용하여 쉽게 달성할 수 있습니다. 행렬로 작업하는 경우 이를 달성하기 위해 반복하는 것 외에 효과적인 방법은 무엇입니까?
dt = New Table("Test");
dt << New Column("Random-1",Numeric,Continuous,<< set values(Random Index(10^3,10^2)));
dt << New Column("AltToLag",Numeric,Continuous,Formula(If(Row()==1,0,Lag(:Name("Random-1")))));Re: 데이터 테이블 대신 행렬로 작업할 때 Lag()의 대안다음은 제가 사용했던 Vince 솔루션의 변형입니다. 그것 ~할 것 같다 또는 ~할 것 같다 요구 사항을 포착하지는 않지만 필요한 조작을 수행하는 방법을 설명할 수 있습니다.
R = [4, 6, 6, 5, 8, 7];
lag = 1;
// describe the adjustment
modamount = [1, -1];
// lagged values dont need the last value
lagged = R[1 :: N Rows( R ) - lag];// [4, 6, 6, 5, 8]
// adjustment is based on lagged values. add 1 for indexing.
adjust = modamount[1 + Mod( lagged, 2 )];// [1, 1, 1, -1, 1]
// source data does not need the first value
source = R[1 + lag :: N Rows( R )]; // [6, 6, 5, 8, 7]
// combine the adjustment with the source
combine = adjust + source; // [7, 7, 6, 7, 8]
// prepend a zero
answer = 0 |/ combine; // [0, 7, 7, 6, 7, 8]
Re: 데이터 테이블 대신 행렬로 작업할 때 Lag()의 대안확신하는.따라서 수식을 보면(첫 번째 행 = 0 제외)
If( Mod( Lag( :RandomList ), 2 ) == 0,
:RandomList[Row()] + 1,
:RandomList[Row()] - 1
)
나는 그것을 세 부분, 즉 지연, mod == 0 지연 확인, 그리고 그 else 표현으로 봅니다.
그래서 난 먼저 지연을 해
lv = lag_matrix(v, 1);
그런 다음 모드 벡터를 얻습니다.
mod_vector = lv / 2 - floor(lv/2);
하지만 방금 모드가 벡터에서 작동한다는 것을 깨달았습니다.
mod_vector = mod(lv, 2);
훨씬 더 빠릅니다
그런 다음 다음을 수행하여 부울 벡터를 얻습니다.
mod_Vector == 0 및 loc()을 수행하여 lag(1)의 mod(2)가 0인 행을 찾습니다.
loc_vector = loc(mod_vector==0);
loc_Vector는 if 문과 일치하는 행입니다.
Mod( Lag( :RandomList ), 2 ) == 0
그런 다음 else 문 행을 얻으려면 모두 1로 구성된 벡터를 만들고 loc_Vector 행을 0으로 설정하고 loc()를 수행하여 선택을 반전시킵니다.
invert_vector = J(nrows(v), 1);
invert_vector[loc_vector] = 0;
invert_vector = loc(invert_vector);
따라서 두 벡터를 연결하고 정렬하면 1::nrows()여야 합니다.
그런 다음 if 표현식의 행을 +1로 설정하고 else 표현식의 행을 -1로 설정했습니다.
v[loc_vector] = v[loc_vector] + 1;
v[invert_vector] = v[invert_vector] - 1;
마지막으로 첫 번째 행을 0으로 설정합니다.
v[1] = 0;
Re: 데이터 테이블 대신 행렬로 작업할 때 Lag()의 대안@vince_faller ,
솔루션을 제공해 주셔서 감사합니다. 질문하기에는 너무 많지 않다면 사고 과정과 그것이 어떻게 작동하는지 친절하게 설명해 주시겠습니까?
나는 당신이 lag_matrix 함수, mod 함수 및 loc()의 조합을 사용하고 있는 것을 보았지만 논리를 잘 이해하지 못합니다.
프로세스를 배울 수 있도록 논리의 폭을 크게 높이 평가할 것입니다(다시 물어볼 것이 너무 많지 않은 경우에만).
Re: 데이터 테이블 대신 행렬로 작업할 때 Lag()의 대안슈퍼 사용자 친화적이지는 않지만 벡터와 열을 실행할 때 내 컴퓨터에서는 이러한 모든 단계가 여전히 ~3배 더 빠릅니다(436:135 us).더 빠르게 만들기 위해 할 수 있는 최적화도 분명히 있습니다. 1000행으로 설정하면 4배 정도 빨라졌습니다(1057:227us). 또한 분명히 그들은 Apply를 제거했습니다. 안타깝습니다.
dt = New Table( "Test" );
dt << New Column( "RandomList", Numeric, Continuous, <<SET values=""> 0,
lag_vector = lag_vector[1 :: n - Abs( lag )];
new_mat = empty_mat |/ mat[lag_vector, 0];
, //else
lag_vector = lag_vector[Abs( lag ) + 1 :: n];
new_mat = mat[lag_vector, 0] |/ empty_mat;
);
new_mat;
);
v = Column( dt, "RandomList" ) << Get Values;
check_vector = Column(dt, "DesFunc") << Get Values;
time_vector = HPTime();
//lag the vector
lv = lag_matrix(v, 1);
//mod the vector
mod_vector = lv / 2 - floor(lv/2);
//find the mods you want
loc_vector = loc(mod_vector==0);
//invert to find the mods you don't want
invert_vector = J(nrows(v), 1);
invert_vector[loc_vector] = 0;
invert_vector = loc(invert_vector);
//assign values
v[loc_vector] = v[loc_vector] + 1;
v[invert_vector] = v[invert_vector] - 1;
//set first row to 0
v[1] = 0;
time_vector = HPTime()-time_vector;
show(all(v == check_vector));
show(time_column, time_vector);
</SET>
이것이 조금 도움이 되기를 바랍니다.
Re: 데이터 테이블 대신 행렬로 작업할 때 Lag()의 대안@vince_faller ,
루프 없이 행렬에서 다음을 구현하도록 도와주실 수 있나요?
dt = New Table("Test");
dt << New Column("RandomList",Numeric,Continuous,<< Set Values(Random Index(10^3,10^2)))
<< New Column("DesFunc",Numeric,Continuous,Formula(If(Row() == 1,0,If(Mod(Lag(:RandomList),2)==0,:RandomList[Row()]+1,:RandomList[Row()]-1))));또한 스크립팅 인덱스에서 apply() 또는 applyOver() 함수를 찾을 수 없습니다. 저는 JMP 14를 사용하고 있습니다. JMP Pro인가요?
Re: 데이터 테이블 대신 행렬로 작업할 때 Lag()의 대안실제로 무엇을 하려고 하시나요?행렬이 일반적으로 더 빠르다는 것이 맞습니다. 그러나 행렬을 반복하면 (내 경험상) 일반적으로 이점을 잃게 됩니다.JMP 14에는 이제 apply() 및 applyOver() 함수가 있지만 이를 사용해 본 적이 별로 없습니다.
Re: 데이터 테이블 대신 행렬로 작업할 때 Lag()의 대안@XanGregg , @Craige_Hales
Xan 또는 Craige- 가능하다면 JSL의 수많은 예제를 통해 벡터화를 수행하는 방법을 자세히 다루는 블로그 게시물을 작성해 주시기 바랍니다. 이 주제는 SAS, R, Matlab 및 기타 환경에서 자세히 다룹니다. JMP에서도 비슷한 것을 보고 싶습니다. 비슷한 내용이 이미 존재한다면 관심을 갖도록 요청하겠습니다.
SAS 블로그 - https://blogs.sas.com/content/iml/2013/05/15/Vectorize-computations.html
Re: 데이터 테이블 대신 행렬로 작업할 때 Lag()의 대안@gzmorgan0 ,
제가 요구하려는 것은 루프를 피하고 벡터화된 코드에 의존하는 방법입니다. 코드를 보다 효율적으로 만들기 위해 루프를 행렬 함수로 바꾸는 것이 좋습니다( https://community.jmp.com/t5/JMP-Blog/JSL-Tip-Replace-Loops-with-Functions-on-Matrices/ba-p/29783 ) . 이는 R에서는 패밀리 적용 기능을 통해, Matlab에서는 일부 매트릭스 기능 또는 사용자 정의 기능을 통해 달성됩니다. 이 경우 지연()을 찾기 위해 루프를 작성하는 대신 행렬에 벡터화된 코드를 구현할 수 있는 방법이 있는지 요청합니다.
@gzmorgan0 썼다:
우데이,
나는 당신이 무엇을 요구하는지 모르겠습니다. j-1행만 참조하면 됩니다. 스크립트는 lag1 및 dif1 결과를 모두 표시합니다.
Names Default to Here(1);
dt = Open("$sample_data/Big Class.jmp");
bcmat = dt << get as matrix; //Matrix(40,3)
for(j=2, j<=nrow(dt), j++,
lag1 = bcmat[j-1,0];
dif1 = bcmat[j,0] - bcmat[j-1,0];
show( lag1, dif1)
);
귀하가 제공한 예에서 루프를 작성하고 이에 상응하는 lag()를 얻는 것이 쉽다는 것을 확실히 이해합니다. 그러나 데이터 세트의 크기나 반복 횟수가 증가하면 코드 속도가 느려집니다. 나는 효율적인 대체, 즉 JSL의 행렬에 대한 반복 작업을 구현하는 것과 동등한 벡터화를 찾고 있습니다.
Re: 데이터 테이블 대신 행렬로 작업할 때 Lag()의 대안우데이,
나는 당신이 무엇을 요구하는지 모르겠습니다. j-1행만 참조하면 됩니다. 스크립트는 lag1 및 dif1 결과를 모두 표시합니다.
Names Default to Here(1);
dt = Open("$sample_data/Big Class.jmp");
bcmat = dt << get as matrix; //Matrix(40,3)
for(j=2, j<=nrow(dt), j++,
lag1 = bcmat[j-1,0];
dif1 = bcmat[j,0] - bcmat[j-1,0];
show( lag1, dif1)
);Re: 데이터 테이블 대신 행렬로 작업할 때 Lag()의 대안@vince_faller ,
제공해 주신 솔루션에 감사드립니다. 전체 행렬이 아닌 이전 행만 가져오도록 이 함수를 수정하는 방법이 있습니까?
아마도 적절한 질문은 함수를 사용하여 행렬 주위를 반복하는 벡터화된 형식이 무엇인지일 것입니다. 이는 루프보다 훨씬 빠른 R의 함수를 적용하는 것과 유사합니다.
Re: 데이터 테이블 대신 행렬로 작업할 때 Lag()의 대안이것이 당신에게 효과가 있습니까?
names default to here(1);
lag_matrix = function({mat, lag}, {DEFAULT LOCAL},
n = nrows(mat);
lag_vector = 1::n;
empty_mat = J(abs(lag), ncols(mat), .);
if(lag>0,
lag_vector = lag_vector[1::n-abs(lag)];
new_mat = empty_mat|/mat[lag_vector, 0];
, //else
lag_vector = lag_vector[abs(lag)+1::n];
new_mat = mat[lag_vector, 0]|/empty_mat;
);
new_mat;
);
lag_matrix((14::28)`||(28::42)`, -1);