有没有办法如何从XSLT 2.0或3.0的输入值中获得90,95或99百分位数?以下是此问题How to print percentile using xsl的代码,但无效。这给了我两个值的平均值,而不是一个想要百分位值的值。
从这个"在线计算器"结果为5. https://www.emathhelp.net/calculators/probability-statistics/percentile-calculator/?i=2%2C4%2C3%2C1%2C5&p=90&steps=on
XML
<root>
<value t="5"></value>
<value t="1"></value>
<value t="2"></value>
<value t="4"></value>
<value t="3"></value>
</root>
XSL
<xsl:template match="/">
<xsl:variable name="thisPercentile">
<xsl:call-template name="percentiles">
<xsl:with-param name="responsetimes" select="/root/*/@t" />
<xsl:with-param name="percentile" select="0.9" />
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="$thisPercentile" />
</xsl:template>
<xsl:template name="percentiles">
<xsl:param name="responsetimes" select="." />
<xsl:param name="percentile" select="." />
<xsl:variable name="sortedresponsetimes">
<xsl:for-each select="$responsetimes">
<xsl:sort data-type="number" />
<xsl:element name="time">
<xsl:value-of select="." />
</xsl:element>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="n" select="count($responsetimes)-1" />
<xsl:variable name="k" select="floor($percentile*$n)+1" />
<xsl:variable name="f" select="($percentile*$n+1)-$k" />
<xsl:variable name="a0" select="$sortedresponsetimes[1]/time[$k]" />
<xsl:variable name="a1" select="$sortedresponsetimes[1]/time[$k+1]" />
<xsl:value-of select="$a0 + ( $f * ( $a1 - $a0))" />
</xsl:template>
转换后的输出
4.6
答案 0 :(得分:2)
在XPath 3.1中使用sort
函数,您可以在链接页面上实现该算法
<xsl:function name="mf:percentile" as="xs:decimal">
<xsl:param name="input-sequence" as="xs:decimal*"/>
<xsl:param name="p" as="xs:integer"/>
<xsl:sequence select="let $sorted-input := sort($input-sequence),
$i := round($p div 100 * count($sorted-input))
return $sorted-input[$i]"/>
</xsl:function>
在完整的样本中
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="xs mf"
version="3.0">
<xsl:function name="mf:percentile" as="xs:decimal">
<xsl:param name="input-sequence" as="xs:decimal*"/>
<xsl:param name="p" as="xs:integer"/>
<xsl:sequence select="let $sorted-input := sort($input-sequence),
$i := round($p div 100 * count($sorted-input))
return $sorted-input[$i]"/>
</xsl:function>
<xsl:output method="text"/>
<xsl:template match="root">
<xsl:value-of select="mf:percentile(value/@t, 90)"/>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/bFukv8u
在XSLT / XPath 2.0中,您可以使用perform-sort
,然后在函数中使用本地XSLT变量:
<xsl:function name="mf:percentile" as="xs:decimal">
<xsl:param name="input-sequence" as="xs:decimal*"/>
<xsl:param name="p" as="xs:integer"/>
<xsl:variable name="sorted-input" as="xs:decimal*">
<xsl:perform-sort select="$input-sequence">
<xsl:sort select="."/>
</xsl:perform-sort>
</xsl:variable>
<xsl:variable name="i" select="round($p div 100 * count($sorted-input))"/>
<xsl:sequence select="$sorted-input[$i]"/>
</xsl:function>