我需要使用PHP脚本计算我在csv文件中从Google财经导入的股票价格的平均值和标准差。我可以将这些csv文件导入mysql到不同的表中。我打算将每个库存存储在一个单独的表中,以使其开始时不那么复杂。
在电子表格中,计算最后n行的运行平均值相当容易。但是,一旦我导入到MySQL,我就会对如何计算从第20行开始的每行的最后20行的平均值感到震惊(显然知之甚少)。
从Google财经导入时,我的表格结构如下所示:
+-------------+---------+
| id | close |
+-------------+---------+
| a1447128000 | 1353.5 |
| 1 | 1356.2 |
| 2 | 1352.65 |
| 3 | 1355.65 |
| 4 | 1354.2 |
| 5 | 1356 |
| 6 | 1351 |
| 7 | 1352.5 |
| 8 | 1350 |
| 9 | 1349.3 |
| 10 | 1343.6 |
| 11 | 1342.4 |
| 12 | 1340.7 |
| 13 | 1338.5 |
| 14 | 1340.5 |
| 15 | 1338.5 |
| 16 | 1340 |
| 17 | 1335.25 |
| 18 | 1340.5 |
| 19 | 1341 |
| 20 | 1338.95 |
| 21 | 1334 |
| 22 | 1326.5 |
| 23 | 1320.1 |
| 24 | 1318 |
+-------------+---------+
我正在尝试实现这样的输出:
+-------------+---------+-----------+--------------------+
| id | close | average | standard deviation |
+-------------+---------+-----------+--------------------+
| a1447128000 | 1353.5 | | |
| 1 | 1356.2 | | |
| 2 | 1352.65 | | |
| 3 | 1355.65 | | |
| 4 | 1354.2 | | |
| 5 | 1356 | | |
| 6 | 1351 | | |
| 7 | 1352.5 | | |
| 8 | 1350 | | |
| 9 | 1349.3 | | |
| 10 | 1343.6 | | |
| 11 | 1342.4 | | |
| 12 | 1340.7 | | |
| 13 | 1338.5 | | |
| 14 | 1340.5 | | |
| 15 | 1338.5 | | |
| 16 | 1340 | | |
| 17 | 1335.25 | | |
| 18 | 1340.5 | | |
| 19 | 1341 | 1346.5975 | 6.885664002 |
| 20 | 1338.95 | 1345.87 | 6.886588415 |
| 21 | 1334 | 1344.76 | 6.921155973 |
| 22 | 1326.5 | 1343.4525 | 7.729917124 |
| 23 | 1320.1 | 1341.675 | 8.7418605 |
| 24 | 1318 | 1339.865 | 9.660513703 |
+-------------+---------+-----------+--------------------+
正如您所注意到的那样,对于行ID 19,平均值将是最后20行。对于行ID 20,平均值将是最后20行......依此类推。
我甚至想知道是否可以使用php的foreach循环遍历每一行并获得最后20行的平均值但是当我尝试时我完全迷失了。
我无法在此处获得任何线索(在MySQL或PHP中)。如果有任何关于如何解决此问题的建议,将不胜感激。
答案 0 :(得分:2)
下面的代码粗略地显示了你可以做什么
$averages = array();
while($row = $result->fetch_assoc())
{
$sum = 0;
$arraySize = array_push($averages,$row['close']);
if($arraySize > 20)
{
array_shift($averages)
}
foreach($averages as $value)
{
$sum += $value;
}
$average = $sum / $arraySize
}
从代码开头的空数组开始,在MySQL结果循环的每次迭代中使用array_push,它还会在将值添加到数组后返回数组的大小。然后检查这个值,如果它大于20,你使用array_shift将所有内容向下移1,从而删除第一个值
如果你不想计算数组中值的数量是否小于20时,只需将foreach
包裹起来,然后在if语句中显示该行
答案 1 :(得分:1)
page-whatever.php
答案 2 :(得分:1)
不确定你将如何显示平均值,但这应该有效。
$values = array(); $sum = 0; $i = 0; while($row = $result->fetch_assoc()) { $values[] = $row['close']; $sum += $row['close']; if($i > 19) { $sum -= $values[$i - 20]; $row['average'] = $sum/20; } }
答案 3 :(得分:1)
以下是适合我的完整代码。感谢@ Memor-X,@origenes和@Terminus,因为这段代码是使用他们的回复开发的。我甚至使用相同的逻辑计算标准偏差。
$averages = array();
while($row = $result->fetch_assoc())
{
$sum = 0;
$arraySize = array_push($averages,$row['close']);
if($arraySize > 20)
{
array_shift($averages);
}
if($arraySize > 19) {
$sum = array_sum($averages);
$average = $sum /20;
echo "average: " .$average ."<br/>";
}
$sumOfDiff =0;
if($arraySize > 19) {
foreach($averages as $valueitem)
{
$sumOfDiff += ($valueitem - $average)*($valueitem - $average);
}
$variance = $sumOfDiff/20;
$stddev = sqrt($variance);
$upperband = $average + ($stddev *2);
$lowerband = $average - ($stddev *2);
echo "variance: " .$variance."<br/>";
echo "standard deviation: " .$stddev ."<br/>";
}
}