PHP平均数组中的n个元素组

时间:2018-01-23 09:56:06

标签: php

我有一个通过上传和读取excel文件创建的数组。

创建数组的脚本是:

$values = array();
for($i=1;$i<=$arrayCount;$i++){
    $date = trim($allDataInSheet[$i]["A"]);
    $dir = trim($allDataInSheet[$i]["B"]);
    $sinvalue= sin(deg2rad($dir));
    $cosvalue= cos(deg2rad($dir));            
    $values[] = "('$date', $sinvalue,$cosvalue)";
}

此阵列正在运行。通常它有1440个元素。我想从第一个元素开始,取5个组中的$sinvalue$cosvalue的平均值。进一步超出5的平均值(它将是288个元素),我想找到12个组中的平均值。最后将有24个值。如何为此做一个for循环?

数据看起来像这样:

Array ( 
    [0] => ('date', 0,1) 
    [1] => ('2018-01-23 00:01:00', -0.374606593415912,-0.9271838545667874) 
    [2] => ('2018-01-23 00:02:00', -0.4383711467890778,0.8987940462991668) 
    [3] => ('2018-01-23 00:03:00', 0.6946583704589975,-0.719339800338651) 
    [4] => ('2018-01-23 00:04:00', 0.9063077870366499,0.4226182617406994) 
    [5] => ('2018-01-23 00:05:00', -0.9510565162951535,-0.3090169943749476) 
    [6] => ('2018-01-23 00:06:00', -0.743144825477394,-0.6691306063588585) 
    [7] => ('2018-01-23 00:07:00', 0.9876883405951378,0.1564344650402309) 
    [8] => ('2018-01-23 00:08:00', -0.7986355100472928,-0.6018150231520483) 
    [9] => ('2018-01-23 00:09:00', 0.2079116908177593,-0.9781476007338057) 
    [10] => ('2018-01-23 00:10:00', 0.2756373558169992,-0.9612616959383189) 
    [11] => ('2018-01-23 00:11:00', -0.9396926207859082,-0.3420201433256694) 
    [12] => ('2018-01-23 00:12:00', -0.4539904997395462,-0.8910065241883681) 
    [13] => ('2018-01-23 00:13:00', 0.9961946980917455,0.08715574274765836) 
    [14] => ('2018-01-23 00:14:00', -0.6819983600624984,-0.7313537016191706) 
    [15] => ('2018-01-23 00:15:00', -0.9961946980917455,0.08715574274765789) 
    [16] => ('2018-01-23 00:16:00', 0.4067366430758,-0.913545457642601) 
    [17] => ('2018-01-23 00:17:00', -0.5000000000000001,-0.8660254037844386) 
    [18] => ('2018-01-23 00:18:00', 0.9135454576426009,0.4067366430758004) 
    [19] => ('2018-01-23 00:19:00', 0.819152044288992,-0.5735764363510458) 
    [20] => ('2018-01-23 00:20:00', 0.6946583704589975,-0.719339800338651) 
    [21] => ('2018-01-23 00:21:00', 0.7986355100472928,0.6018150231520484) 
    [22] => ('2018-01-23 00:22:00', 0.8746197071393959,-0.484809620246337) 
    [23] => ('2018-01-23 00:23:00', -0.2249510543438653,0.9743700647852351) 
    [24] => ('2018-01-23 00:24:00', 0.6427876096865393,0.766044443118978) 
    [25] => ('2018-01-23 00:25:00', 0.5877852522924732,-0.8090169943749473) 
    [26] => ('2018-01-23 00:26:00', 0.7986355100472928,0.6018150231520484) 
    [27] => ('2018-01-23 00:27:00', 0.992546151641322,0.1218693434051475) 
    [28] => ('2018-01-23 00:28:00', -0.9961946980917455,0.08715574274765789) 
    [29] => ('2018-01-23 00:29:00', 0.9335804264972017,0.3583679495453002) 
    [30] => ('2018-01-23 00:30:00', -0.961261695938319,-0.2756373558169989) 
    [31] => ('2018-01-23 00:31:00', 0.4383711467890777,-0.8987940462991668) 
    [32] => ('2018-01-23 00:32:00', -0.9993908270190958,0.03489949670250039) 
    [33] => ('2018-01-23 00:33:00', -0.743144825477394,-0.6691306063588585) 
)

2 个答案:

答案 0 :(得分:1)

首先,您应该重新设计数据结构。您在$values中汇总字符串中的值,然后很难提取和使用各个组件。

$values = array();
for($i=1;$i<=$arrayCount;$i++){
    $date = trim($allDataInSheet[$i]["A"]);
    $dir = trim($allDataInSheet[$i]["B"]);
    $sinvalue= sin(deg2rad($dir));
    $cosvalue= cos(deg2rad($dir));            
    $values[] = array(
        'date' => $date,
        'sin'  => $sinvalue,
        'cos'  => $cosvalue,
    );
}

现在,可以应用多个array functions来完成这项工作。

PHP不提供计算数字列表平均值的函数,但编写一个函数并不困难:

function average(array $input)
{
    return array_sum($input) / count($input);
}

'sin'中提取与$values相关联的值,将列表拆分为5个项目的块,将函数average()应用于每个块。结果是288个值的列表。

$avg288 = array_map(
    'average',
    array_chunk(
        array_column($values, 'sin'),
        5
    )
);

与上面类似,将288个平均值列表拆分为24个12个值的块,将average()应用于每个块,获取24个数字的列表。

$avg24 = array_map(
    'average',
    array_chunk(
        $avg288,
        12
    )
);

了解array_sum()count()array_column()array_chunk()array_map()

<强>更新

在PHP 5.4上array_column()不起作用(因为它是在PHP 5.5中引入的。)。

在这种情况下,您可以在初始循环中计算array_column()返回的数组,其中创建了$values

$values = array();
$sins = array();
for($i=1;$i<=$arrayCount;$i++){
    $date = trim($allDataInSheet[$i]["A"]);
    $dir = trim($allDataInSheet[$i]["B"]);
    $sinvalue= sin(deg2rad($dir));
    $cosvalue= cos(deg2rad($dir));            
    $values[] = array(
        'date' => $date,
        'sin'  => $sinvalue,
        'cos'  => $cosvalue,
    );
    $sins[] = $sinvalue;
}

在计算$sins时使用array_column($values, 'sin')代替$avg288

答案 1 :(得分:0)

虽然Axiac的解决方案很好。在他发布之前我已经开始研究我的解决方案。我访问的方法略有不同。我没有使用array_maparray_chunk

我的主要问题,正如我在评论中所解释的那样,是您的数据结构,具体而言,您在代码中通过关联数组访问方向;
$dir = trim($allDataInSheet[$i]["B"]);

但是您提供给我们的数据显示了正常的索引数组;
[1] => ('2018-01-23 00:01:00', -0.374606593415912,-0.9271838545667874)

因此trim($allDataInSheet[$i]["B"]);应返回&#34;未定义索引&#34; B&#34; &#34; ..无论如何......
这是我的解决方案:

我循环遍历数组的所有元素,我检查它是否是5或12的模块。然后我将当前索引传递给平均函数,该函数访问数组的下一个5/12元素并返回数组中的平均sin + cos。

如果这不起作用,那是因为我上面提到的...... $allDataInSheet[$i]["B"]应为$allDataInSheet[$i][1]

<?php

$allDataInSheet = array();
$arrayCount = count($allDataInSheet);

$fiveGroup = array();
$twelveGroup = array();

//loop the array
for($i=1;$i<=$arrayCount;$i++){
    //modula function to see if group of 5
    if($i%5 === 0){
       $fiveGroup[] = calculateAverage($i,5,$allDataInSheet);
    //modula to see if group of 12
    }else if($i%12===0){
       $twelveGroup[] = calculateAverage($i,12,$allDataInSheet);
    }

}

//output the 5 grouped averages
print_r($fiveGroup);
//output the 12 grouped averages
print_r($twelveGroup);    


function calculateAverage($indexStart,$indexEnd,$array){
    //initilize the arrays
    $sinGroup = array();
    $cosGroup = array();

    //loop over elements
    for($i=1; $i<$indexEnd; $c++){
        //Assign the values to array
        $sinGroup[] = sin(deg2rad($array[$indexStart+$c]["B"]));
        $cosGroup[] = cos(deg2rad($array[$indexStart+$c]["B"]));
        //$sinGroup[] = sin(deg2rad($array[$indexStart+$c][1]));
        //$cosGroup[] = cos(deg2rad($array[$indexStart+$c][1]));
    }

    //work out the average
    $sinAverage = array_sum($sinGroup) / count($sinGroup);
    $cosAverage = array_sum($cosGroup) / count($cosGroup);

    //return the averages
    return array($sinAverage,$cosAverage);

}