항목이 다른 열 B의 null이 아닌 마지막 10개 항목의 평균/중앙값/모드와 동일한 열 A를 어떻게 구성합니까?안녕하십니까,
숫자와 많은 null 값(70-80% null)이 있는 열 A(약 15,000개 행)가 있습니다.
나는 행 i에서 다음의 평균과 같은 열 B를 구성하고 싶습니다: *A*의 마지막 10개의 null이 아닌 값
--> 이것은 A[row i-1] , A[row i-2], ...를 의미하고 10개의 null이 아닌 값을 가질 때까지 뒤로 이동합니다(또는 행 1에 도달하면 임의의 숫자 <= 10 얻은 null이 아닌 값)
나는 또한 중간값과 모드를 의미하는 것 외에도 다음과 같은 모드의 부드러운 버전을 만들고 싶습니다.
먼저 10개의 null이 아닌 값에 대해 가우스 평활화를 수행하고 해당 분포의 argmax(모드)를 취합니다.
어떤 생각이나 제안을 해주셔서 감사합니다!
***
솔루션 아이디어: 내가 가진 한 가지 생각은 마지막 10개의 null이 아닌 값으로 여러 가지 다른 계산을 수행하고 싶었기 때문에 먼저 항목이 마지막 10개의 null이 아닌 값과 동일한 배열인 열 C를 생성해야 한다는 것입니다. B1(평균), B2(중간), B3(평활 모드)를 생성하기 위해 열 C에서 작동하는 3개의 공식을 수행할 수 있습니다.
다음은 이 열 C 배열을 구성하는 방향으로 이동하는 몇 가지 코드 조각입니다.
//step 1 grab the last say 50 entries (some fixed amount that will likely have 10 non-nulls)
For Each Row( dt_join,
to = Row();
If( to - 50 < 0,
from = 1,
from = to - 50); // Quantile( 0.5,
values = :away_1g_pull_seconds[Index( From, To )] < 50, Break());
);
//step 2 convert array to list, drop nulls, convert list of first 10 entries back to array ...
//I don't know how to assign this to a row of C
num_lag = 10;
values = dt_join:A[Index( From, To )] ;
MyList = Remove(as list(values)[1], as list(Loc(as list(values)[1], .)) ); //convert array to list and remove nulls
Mat = Number Col Box("", MyList[1:10]) << get as matrix; //hack convert to array
데이터 테이블스크립팅Re: 다른 열 B의 null이 아닌 마지막 10개 항목의 평균/중앙값/모드와 동일한 항목을 가진 열 A를 어떻게 구성합니까?다음은 첫 번째 요청의 시작입니다.열 A의 마지막 10개 값에 대한 평균을 만들고 평균을 열 B에 넣습니다.
지금은 이것에 대해 더 일할 시간이 없습니다.아마 이번 주말에.
Names Default To Here( 1 );
dt = Current Data Table();
theMatrix = [];
dt << New Column( "B" );
For Each Row(
If( Is Missing( :A ) == 0,
theMatrix = Matrix( :a ) || theMatrix
);
If( Length( theMatrix ) > 10,
theMatrix[1, 11] = []
);
:B = Mean( theMatrix );
);
Re: 다른 열 B의 null이 아닌 마지막 10개 항목의 평균/중앙값/모드와 동일한 항목을 가진 열 A를 어떻게 구성합니까?@DonMcCormack 이것은 좋은 도전 문제가 될 것입니다.
나는 이것이 효과가 있고 합리적으로 효율적이라고 생각합니다.
nr = 15000;
dt = New Table( "Untitled",
Add Rows( nr ),
New Column( "a", Numeric, "Continuous", Format( "Best", 12 ), Set Values( J( nr, 1, If( Random Uniform() < .3, Random Integer( 0, 1 ), . ) ) ) )
);
lookback = 10;
dt << New Column( "b" || Char( lookback ),
formula(
// make a helper to help look up the non-missing rows
helper = As Constant( // AsConstant is for efficiency
temp = dt << getrowswhere( !Is Missing( a ) );
// temp is the non-missing row numbers. Make sure row 1
// is included, even if missing, because LocSorted will
// return [1] when a smaller value would have been better.
If( temp[1] != 1,
Insert Into( temp, 1, 1 )
);
temp; // this is assigned to 'helper'
);
currentrow = Row(); // this is the target for a new mean, etc
end = Loc Sorted( helper, currentrow )[1]; // end is the last non missing row before or at the target
start = Max( 1, end - lookback + 1 ); // start is the row 'lookback' rows earlier
rowset = helper[start :: end]; // rowset is the set of nonmissing rows, possibly including a missing value at row 1.
// it is OK if a missing value is present; mean/median/mode ignore it.
// grab the rowset from column a and report the statistic...
Mean( dt[rowset, {a}] );// median, mode
)
);
Re: 다른 열 B의 null이 아닌 마지막 10개 항목의 평균/중앙값/모드와 동일한 항목을 가진 열 A를 어떻게 구성합니까?안녕하십니까,
다음은 누락이 없는 중간 테이블을 사용하여 이를 수행하는 또 다른 방법으로, 더 간단한 수식을 허용합니다.
Names Default To Here( 1 );
dt = Current Data Table();
//get nonmissing rows of table and put them in a new table
m = dt << get rows where( !Is Missing( :a ) );
dt2 = New Table( "xxx", invisible, <<ADD rows=""></ADD>
원래 테이블이 작은 경우(예: 약 15K 행) 두 가지 접근 방식이 유사하게 수행됩니다. 첫 번째는 터치 속도가 더 빠릅니다.

원래 테이블이 커짐에 따라 "별도의 테이블" 접근 방식이 약 1/10의 시간으로 실행되어 훨씬 더 잘 확장되는 것 같습니다. 다음은 150K 행의 예입니다.

가능한 거래 차단기(??)는 이 접근 방식이 소스 테이블에 수식을 생성하지 않으므로 새 데이터가 추가될 때마다 이를 다시 실행해야 한다는 것입니다.
실험하고 싶은 경우를 대비하여 150K 행 파일을 첨부했습니다.
건배,
브래디
Re: 다른 열 B의 null이 아닌 마지막 10개 항목의 평균/중앙값/모드와 동일한 항목을 가진 열 A를 어떻게 구성합니까?여기에 몇 가지 더 많은 결과가 있습니다. "별도의" 방법은 선형적으로 확장되는 것 같습니다. "동일한 테이블" 방식은 450,000행 북쪽 어딘가에 있는 것처럼 보입니다. 이유를 모르겠습니다.


Re: 다른 열 B의 null이 아닌 마지막 10개 항목의 평균/중앙값/모드와 동일한 항목을 가진 열 A를 어떻게 구성합니까?helper=AsConstant의 경우 여전히 N^2라고 생각합니다. 그것은 100K 배열을 400K 번 복사하는 것입니다 ...
편집: 추측이 확인되었습니다. 그러나 수식에서 도우미를 들어 올려도 여전히 Brady의 코드보다 약 절반 정도 빠릅니다.
하지만...Jim의 코드를 더 빠르게 조정할 수 있습니다...
dt = Current Data Table();
startTime = Tick Seconds();
theMatrix = {., ., ., ., ., ., ., ., ., .};
z = .;
dt << New Column( "B" );
dt << begindataupdate;
For Each Row(
v = :A;
If( v == v,
Insert Into( theMatrix, v );
Remove From( theMatrix, 1 );
z = Mean( theMatrix );
);
:B = z;
);
stopTime = Tick Seconds();
Show( stopTime - startTime );
dt << enddataupdate;Re: 다른 열 B의 null이 아닌 마지막 10개 항목의 평균/중앙값/모드와 동일한 항목을 가진 열 A를 어떻게 구성합니까?귀하의 모든 응답에 감사드립니다.
자세히 읽을 기회가 없었지만 읽을 때 더 많이 응답하겠습니다.
최고,
조
Re: 다른 열 B의 null이 아닌 마지막 10개 항목의 평균/중앙값/모드와 동일한 항목을 가진 열 A를 어떻게 구성합니까?내 접근 방식보다 훨씬 더 우아합니다.
Re: 다른 열 B의 null이 아닌 마지막 10개 항목의 평균/중앙값/모드와 동일한 항목을 가진 열 A를 어떻게 구성합니까?와......이 운동은 나에게 많은 것을 가르쳐 줬어.내 원래 코드는 작동했지만 대체 방법보다 너무 느려서 시간을 들여 연구했습니다.매우 빠르고 영리한 코드.그 다음에 @Craige_Hales 그의 최신 코드를 제공했는데, 속도는 빠르지만 원래 코드에 접근하는 방식에 매우 가깝습니다.@Craige_Hales 코드가 훨씬 빠릅니다.그리고 가장 큰 차이점은 내가 사용하지 않는다는 것입니다.
Begin Data Update;
.....
End Data Update;
그래서 저는 이제 업데이트가 끝날 때까지 업데이트 메시지를 보류한 것에 대해 큰 감사를 받았습니다.
재미를 주셔서 감사합니다!