我正在寻找一种方法来计算可能包含巨大峰值的给定的一组值的有用平均值。 (例如21,54,34,14,20,300,23或1,1,1,1,200,1,100),当使用标准平均值计算时,尖峰可以将事情关掉。用于规范化平均值的T-SQL
我看着使用中位数,但这并没有真正给出所需的结果。
我想在T-SQL中实现这个
任何想法?
我正在寻找一种方法来计算可能包含巨大峰值的给定的一组值的有用平均值。 (例如21,54,34,14,20,300,23或1,1,1,1,200,1,100),当使用标准平均值计算时,尖峰可以将事情关掉。用于规范化平均值的T-SQL
我看着使用中位数,但这并没有真正给出所需的结果。
我想在T-SQL中实现这个
任何想法?
这样你就可以拿走计算结果之前的最高和最低的25%。
declare @t table (col1 int)
insert @t
select 21 union all
select 54 union all
select 34 union all
select 14 union all
select 20 union all
select 300 union all
select 23 union all
select 1 union all
select 1 union all
select 1 union all
select 1 union all
select 200 union all
select 1 union all
select 100
select avg(col1) from (
select top 67 percent col1 from (
select top 75 percent col1 from @t order by col1
) a order by col1 desc) b
GROUP BY
非代表基团(例如数之间的差异不超过10倍或日志的任何其他碱)HAVING
)(例如小于3)这样做的危险之处在于,您无法确定所有这些尖峰都是微不足道的,值得舍弃。一个人的噪音是另一个人的黑天鹅。
如果您担心大数值会不必要地歪曲您的数据视图,那么最好使用像中值这样的对异常值不敏感的度量。计算比平均值更难,但它会给你一个中心性的测量,而不是由尖峰引起的。
使用中值滤波:
SELECT AVG(value)
FROM (
SELECT TOP 1 value AS median
FROM (
SELECT TOP 50 PERCENT value
FROM mytable
ORDER BY
value
) q
ORDER BY
value DESC
) q
JOIN mytable m
ON ABS(LOG10(value) - LOG10(median)) <= @filter_level
从我+1,很好的解决方案 –
错误时处理零或负值 – MakkyNZ
您可以考虑使用OVER/PARTITION BY之类的窗口函数。这将允许您在特定的行组(例如按名称,日期或小时)内微调排除项。在这个例子中,我借用示例t-clausen.dk中的行,并通过添加名称来展开,以便我们可以演示窗口。
-- Set boundaries, like the TOP PERCENT used in the afore mentioned example
DECLARE @UBOUND FLOAT, @LBOUND FLOAT
SET @UBOUND = 0.8 --(80%) SET @LBOUND = 0.2 --(20%)
--Build a CTE table ;WITH tb_example AS ( select [Val]=21,[fname]='Bill' union all select 54,'Tom' union all select 34,'Tom' union all select 14,'Bill' union all select 20,'Bill' union all select 300,'Tom' union all select 23,'Bill' union all select 1,'Tom' union all select 1,'Tom' union all select 1,'Bill' union all select 1,'Tom' union all select 200,'Bill' union all select 1,'Tom' union all select 12,'Tom' union all select 8,'Tom' union all select 11,'Bill' union all select 100,'Bill' )
--Outer query applies criteria of your choice to remove spikes SELECT fname,AVG(Val) FROM ( -- Inner query applies windowed aggregate values for outer query processing SELECT * ,ROW_NUMBER() OVER (PARTITION BY fname order by Val) RowNum ,COUNT(*) OVER (PARTITION BY fname) RowCnt ,MAX(Val) OVER (PARTITION BY fname) MaxVal ,MIN(Val) OVER (PARTITION BY fname) MinVal FROM tb_example ) TB WHERE -- You can use the bounds to eliminate the top and bottom 20% RowNum BETWEEN (RowCnt*@LBOUND) and (RowCnt*@UBOUND) -- Limits window -- Or you may chose to simply eliminate the Max and MIN values OR (Val > MinVal AND Val < MaxVal) -- Removes Lowest and Highest values GROUP BY fname
在这种情况下,我同时使用标准和AVG val by fname。但天空是你选择用这种技术减轻峰值的限制。
如果你不想要尖峰,那么你需要考虑使用标准偏差。 –