计算 PHP 中 XML 个元素范围的平均值
Calculate mean of a range of XML Elements in PHP
我正在尝试计算 PHP 中 XML 个元素范围的平均值,但尚未找到任何解决方案。
这是 XML 个元素。
<root>
<quoteDay>
<date>2018-02-26</date>
<close>1586,96</close>
</quoteDay>
<quoteDay>
<date>2018-02-23</date>
<close>1577,11</close>
</quoteDay>
<quoteDay>
<date>2018-02-22</date>
<close>1565,5</close>
</quoteDay>
</root>
这里是 PHP 代码:
<?php
$xml = simplexml_load_file("file.xml") or die("Error: Cannot create object");
$id = -1;
$total[] = 0;
foreach ($xml->root as $root) {
foreach ($root->quoteDay as $quoteDay) {
$id ++;
$total[] += $root->quoteDay[$id]->close;
$close = number_format(round($quoteDay->close,0));
echo $quoteDay->date; echo $close; echo $total[$id+1];
}
}
?>
因此,对于每个 quoteDay,我想 return 日期、收盘价和移动平均线。
日期 2018-02-26 将 return 2018-02-26 和 2018-02-23 的 "close" 的平均值 = (1586,96+1577,11)/2。
2018-02-23 的平均值 return (1577,11+1565,5)/2.
如您所见,我曾尝试对每个元素求和一个累计总和,但出于某种原因我不明白它行不通。
如何计算元素的移动平均值?
为了达到你的结果,你需要做几件事:
simplexml_load_file()
已经给了你根,所以你的第一个循环就没有必要了
- 不需要
$total
数组
- 您的 XML 将
,
作为小数点分隔符,但 PHP 使用 .
,因此您需要替换它们以进行数学计算而不丢失小数点(这里我投射到 float
这会让你失去精度,看看 bcmath
来避免这种情况)
- 我假设第一天没有前一天,移动平均线就是当天的值
因此,您的代码将如下所示:
<?php
$xml = simplexml_load_file("a.xml") or die("Error: Cannot create object");
$id = 0;
foreach ($xml->quoteDay as $quoteDay) {
echo "Moving average for ".$quoteDay->date.":".PHP_EOL;
$current = (float) str_replace(",", ".", $quoteDay->close);
$previous = $xml->quoteDay[$id + 1]
? (float) str_replace(",", ".", $xml->quoteDay[$id + 1]->close)
: $current;
$movingMean = ($current + $previous) / 2;
echo $movingMean.PHP_EOL;
echo PHP_EOL;
$id++;
}
结果
Moving average for 2018-02-26:
1582.035
Moving average for 2018-02-23:
1571.305
Moving average for 2018-02-22:
1565.5
要将其概括为 $daysInMovingMean
天,请使用 for
循环使天数达到所需天数,必要时提前停止(即没有剩余天数):
$xml = simplexml_load_file("a.xml") or die("Error: Cannot create object");
$id = 0;
$daysInMovingMean = 3;
foreach ($xml->quoteDay as $quoteDay) {
echo "Moving average for ".$quoteDay->date.":".PHP_EOL;
$sum = 0;
for ($days = 0; $days < $daysInMovingMean; $days++) {
if (!$xml->quoteDay[$id + $days]) break;
$sum += (float) str_replace(",", ".", $xml->quoteDay[$id + $days]->close);
}
$sumovingMean = $sum / $days;
echo $sumovingMean.PHP_EOL;
echo PHP_EOL;
$id++;
}
请注意,在此示例中,如果设置 $daysInMovingMean = 2;
,您将获得与之前相同的结果
我正在尝试计算 PHP 中 XML 个元素范围的平均值,但尚未找到任何解决方案。
这是 XML 个元素。
<root>
<quoteDay>
<date>2018-02-26</date>
<close>1586,96</close>
</quoteDay>
<quoteDay>
<date>2018-02-23</date>
<close>1577,11</close>
</quoteDay>
<quoteDay>
<date>2018-02-22</date>
<close>1565,5</close>
</quoteDay>
</root>
这里是 PHP 代码:
<?php
$xml = simplexml_load_file("file.xml") or die("Error: Cannot create object");
$id = -1;
$total[] = 0;
foreach ($xml->root as $root) {
foreach ($root->quoteDay as $quoteDay) {
$id ++;
$total[] += $root->quoteDay[$id]->close;
$close = number_format(round($quoteDay->close,0));
echo $quoteDay->date; echo $close; echo $total[$id+1];
}
}
?>
因此,对于每个 quoteDay,我想 return 日期、收盘价和移动平均线。
日期 2018-02-26 将 return 2018-02-26 和 2018-02-23 的 "close" 的平均值 = (1586,96+1577,11)/2。
2018-02-23 的平均值 return (1577,11+1565,5)/2.
如您所见,我曾尝试对每个元素求和一个累计总和,但出于某种原因我不明白它行不通。
如何计算元素的移动平均值?
为了达到你的结果,你需要做几件事:
simplexml_load_file()
已经给了你根,所以你的第一个循环就没有必要了- 不需要
$total
数组 - 您的 XML 将
,
作为小数点分隔符,但 PHP 使用.
,因此您需要替换它们以进行数学计算而不丢失小数点(这里我投射到float
这会让你失去精度,看看bcmath
来避免这种情况) - 我假设第一天没有前一天,移动平均线就是当天的值
因此,您的代码将如下所示:
<?php
$xml = simplexml_load_file("a.xml") or die("Error: Cannot create object");
$id = 0;
foreach ($xml->quoteDay as $quoteDay) {
echo "Moving average for ".$quoteDay->date.":".PHP_EOL;
$current = (float) str_replace(",", ".", $quoteDay->close);
$previous = $xml->quoteDay[$id + 1]
? (float) str_replace(",", ".", $xml->quoteDay[$id + 1]->close)
: $current;
$movingMean = ($current + $previous) / 2;
echo $movingMean.PHP_EOL;
echo PHP_EOL;
$id++;
}
结果
Moving average for 2018-02-26: 1582.035
Moving average for 2018-02-23: 1571.305
Moving average for 2018-02-22: 1565.5
要将其概括为 $daysInMovingMean
天,请使用 for
循环使天数达到所需天数,必要时提前停止(即没有剩余天数):
$xml = simplexml_load_file("a.xml") or die("Error: Cannot create object");
$id = 0;
$daysInMovingMean = 3;
foreach ($xml->quoteDay as $quoteDay) {
echo "Moving average for ".$quoteDay->date.":".PHP_EOL;
$sum = 0;
for ($days = 0; $days < $daysInMovingMean; $days++) {
if (!$xml->quoteDay[$id + $days]) break;
$sum += (float) str_replace(",", ".", $xml->quoteDay[$id + $days]->close);
}
$sumovingMean = $sum / $days;
echo $sumovingMean.PHP_EOL;
echo PHP_EOL;
$id++;
}
请注意,在此示例中,如果设置 $daysInMovingMean = 2;