如何对来自多个扁平数组的数据列求平均?

7

假设我有4个数组,每个数组里面的值数量相同:

$array1 = array(0, 7, 5, 0);
$array2 = array(2, 6, 10, 0);
$array3 = array(4, 8, 15, 10);
$array4 = array(6, 7, 20, 10);

我想计算这4个数组的每个索引的平均值。因此,我应该得到类似于以下内容的东西:
array(3, 7, 12.5, 5);
5个回答

3

如果你需要使用6个或更多数组,可以使用以下代码来实现更为动态的用法:

$all_arrays = [
    array(0, 7, 5, 0),
    array(2, 6, 10, 0),
    array(4, 8, 15, 10),
    array(6, 7, 20, 10),
    array(1, 2, 3, 4),
    array(5, 6, 7, 8),
    // more arrays
];

$each_array_count = count($all_arrays[0]); // 4
$all_arrays_count = count($all_arrays); // 6

$output = [];

for ($i = 0; $i < $each_array_count; $i++) {
    for ($j=0; $j < $all_arrays_count; $j++) { 
        $output[$i] += $all_arrays[$j][$i] / $all_arrays_count;        
    }
}

echo "<pre>";
var_dump($output);

输出结果: (演示)

Warning: Undefined array key 0 in /in/E783F on line 20

Warning: Undefined array key 1 in /in/E783F on line 20

Warning: Undefined array key 2 in /in/E783F on line 20

Warning: Undefined array key 3 in /in/E783F on line 20
<pre>array(4) {
  [0]=>
  float(3)
  [1]=>
  float(6)
  [2]=>
  float(10)
  [3]=>
  float(5.333333333333333)
}

3

完全动态函数:

我承担了构建一个完全动态函数的任务,您可以输入任意数量的数组。我还添加了一个null检查,如下面的示例所示,以防您需要跳过数组中的某个值。

函数:

# Function takes in unlimited arrays,
# and returns the average of each index of 
# those arrays as a new array.
function arrayAverage(...$array){

    # Loop through the arrays in the input arguments.
    # For every array, extract all numeric values from each
    # element, and group them by index in a temporary
    # multi-dimensional array. If a value is null, or 
    # cannot be converted into an integer/float, skip it.
    foreach($array as $arr){
        for($i = 0; $i < count($arr); $i++){
            if(!is_null($arr[$i]) && ($arr[$i] == (int)$arr[$i]))
                $temparr[$i][] = (int)$arr[$i];
            elseif(!is_null($arr[$i]) && ($arr[$i] == (float)$arr[$i]))
                $temparr[$i][] = (float)$arr[$i];
        }
    }
        

    # Loop through the multi-dimensional array, 
    # and calculate the average of each.
    # Store results in a separate array to 
    # be returned after the loop is finished.
    for($j = 0; $j < count($temparr); $j++)
        $averages[] = array_sum($temparr[$j]) / count($temparr[$j]);
    
    # Return aforementioned array containing the averages. 
    return $averages;

}

使用/示例:

# Arrays can have a different amount of key=>value pairs,
# and integer values stored as strings can be parsed,
# as shown in "$array2".
$array1 = array(0, 7, 5, 0);
$array2 = array(2, 6, 10, 0, "100");
$array3 = array(4, 8, 15, 10);
$array4 = array(6, 7, 20, 10);

# Example on how to skip values just in case the need arises
# (So averages won't be affected by having an extra number)
$array5 = array(null, null, null, null, 300);

$averages = arrayAverage($array1, $array2, $array3, $array4, $array5);
print_r($averages);

输出:

Array
(
    [0] => 3
    [1] => 7
    [2] => 12.5
    [3] => 5
    [4] => 200
)

实时沙盒演示:

https://onlinephp.io/c/bb513


1
那是一个不错的解决方案,但并不完全符合我的要求。我不想将这些值混在一起。 - KarelRuzicka
如何做到这一点?四个输入数组应该如何转换为您的输入数组? - Nico Haase

2

这里有一个简单的解决方案,但你可以进一步概括并使其更加通用,不过现在它能够工作。可以相应地进行更新:

注意:假设数组的计数与您所提到的相同。

     $result = [];
     for ($i = 0; $i < count($array1); $i++) {
         $result [] = ($array1[$i] + $array2[$i] + $array3[$i] + $array4[$i]) / count($array1);
     }
     dd($result);

接近了,但是如果每个数组有3个元素怎么办?看一下/ count($array1) - SirPilan
您可以根据需要进行泛化。我在答案中提到它可以进一步改进。如果每个数组有3个元素,那么 count($array1) 将起作用。 - dev_mustafa
不,你的计算最终会变成例如:(1+1+1+1) / 3,这已经不是平均值了。 - SirPilan
是的,我已经提到了假设数组的数量和每个数组中的元素都相同。 - dev_mustafa

1
另一种方法:

$arrays = [$array1, $array2, $array3, $array4];

$result = [];
for ($i = 0; $i < count($array1); $i++) {
    $result[] = array_sum(array_column($arrays, $i)) / count($arrays);
}

正在工作example


0

为了获得一个流畅、功能性的代码片段,可以使用array_map()函数来“转置”数据行。这意味着数据列将被传递到自定义函数中。从那里开始进行平均数计算。

代码:(演示)

$array1 = [0, 7, 5, 0];
$array2 = [2, 6, 10, 0];
$array3 = [4, 8, 15, 10];
$array4 = [6, 7, 20, 10];

var_export(
    array_map(
        fn() => array_sum(func_get_args()) / func_num_args(),
        $array1,
        $array2,
        $array3,
        $array4
    )
);
// fn(...$col) => array_sum($col) / count($col), would also work

输出:

array (
  0 => 3,
  1 => 7,
  2 => 12.5,
  3 => 5,
)

请注意,当数组长度不同时,此技术将使用null(计为0)填充列中的空白:Demo
如果您的输入数组是单个多维数组,则可以使用展开运算符将其解包到array_map()中。
var_export(array_map(fn() => array_sum(func_get_args()) / func_num_args(), ...$arrays));

为了避免空值影响计算结果,在进行数学计算之前,请先对它们进行筛选:演示
var_export(
    array_map(
        fn(...$col) => array_sum($col) / count(array_filter($col, fn($v) => !is_null($v))),
        ...$arrays
    )
);
// or:  fn(...$col) => array_sum($col) / count(array_diff($col, ['']))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接