如何構造 A 列,其條目等於另一列 B 的最後 10 個非空條目的平均值/中值/眾數?你好,
我有一列 A(大約 15,000 行),其中包含數字和許多空值(可能 70-80% 為空)。
我想構造一個 B 列,它在第 i 行等於以下平均值:*來自 A* 的最後 10 個非空值
--> 這意味著取 A[row i-1] , A[row i-2], ... 並返回直到你有 10 個非空值(或者如果你到達第 1 行,那麼取任何數字 <= 10你得到的非空值)
除了均值、中位數和眾數之外,我還想做一個平滑版本的眾數,其中:
我首先對 10 個非空值進行高斯平滑......並採用該分佈的 argmax(模式)。
感謝您的任何想法或建議!
***
解決方案的想法:我的一個想法是因為我想用最後 10 個非空值做幾個不同的計算,我應該首先構造一個列 C,其條目是等於最後 10 個非空值的數組......然後我可以做 3 個在 C 列上運行的公式,以產生 B1(平均值)、B2(中間)、B3(平滑模式)。
以下是一些構建此列 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
數據表腳本回复:如何構造 A 列,其條目等於另一列 B 的最後 10 個非空條目的平均值/中值/眾數?這是您第一個請求的開始。它將為 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 );
);
回复:如何構造 A 列,其條目等於另一列 B 的最後 10 個非空條目的平均值/中值/眾數?@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
)
);
回复:如何構造一個列 A,其條目等於另一列 B 的最後 10 個非空條目的平均值/中值/眾數?你好,
這是另一種方法,使用沒有缺失的中間表,它允許更簡單的公式。
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 行文件,以防您想試驗。
乾杯,
布雷迪
回复:如何構造 A 列,其條目等於另一列 B 的最後 10 個非空條目的平均值/中值/眾數?這裡還有一些結果。 “分離”方法似乎是線性縮放的。 “同一張表”方法似乎在 450,000 行以北某處碰壁。 我不確定為什麼。


回复:如何構造一個列 A,其條目等於另一列 B 的最後 10 個非空條目的平均值/中值/眾數?我猜 helper=AsConstant 仍然是 N^2。 這將復制一個 100K 數組 400K 次......
編輯:猜測確認。 但即使將助手從公式中刪除,我的代碼仍然是 Brady 的代碼的一半左右。
但是...吉姆的代碼可以調整得更快...
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;回复:如何構造一個列 A,其條目等於另一列 B 的最後 10 個非空條目的平均值/中值/眾數?非常感謝您的所有回复 - 我被震撼了!
我沒有機會詳細閱讀它們,但我會在閱讀時做出更多回應。
最好的,
喬
回复:如何構造一個列 A,其條目等於另一列 B 的最後 10 個非空條目的平均值/中值/眾數?這真的很好——比我的方法優雅得多。
回复:如何構造一個列 A,其條目等於另一列 B 的最後 10 個非空條目的平均值/中值/眾數?哇......這個練習有沒有教會我很多東西。我的原始代碼有效,但比替代方法慢得多,所以我花時間研究它們。非常快速和聰明的代碼。然後@Craige_Hales提供了他的最新代碼,該代碼速度很快,但採用的方法非常接近我的原始代碼。@Craige_Hales代碼要快得多。大部分的區別在於我缺乏使用
Begin Data Update;
.....
End Data Update;
因此,我現在非常感謝在更新結束之前一直保留更新消息。
謝謝你的樂趣!