如何构造 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;
因此,我现在非常感谢在更新结束之前一直保留更新消息。
谢谢你的乐趣!