简体   繁体   中英

Weighted arithmetic mean of subarray values using php

I have following array:

$array = array(
            array("A",105),
            array("B",125),
            array("C",325),
            array("D",435),
            array("A",110),
            array("A",115),
            array("C",400),
            array("D",650),
            array("E",750)
        );

and would like to do some operations with it just like the following:

First: to group the values of key[0] that are the same, raise them to the 2nd power and sum them. To accomplish that I wrote following code:

$result = array();
foreach ($array as $value){
    if (!array_key_exists($value[0], $result)){
        $result[$value[0]] = array();
    }
    $result[$value[0]][] = pow($value[1],2);
}

array_walk($result, create_function('&$v,$k', '$v = array_sum($v);'));

With that we have the expected result:

Array (
    [A] => 36350
    [B] => 15625
    [C] => 265625
    [D] => 611725
    [E] => 562500
)

Second: to divide each one of these values by the sum of all them together. In other words (or better in other numbers :-)

Sum of them all: 36350 + 15625 + 265625 + 611725 + 562500 = 1491825

then, the division:

[A] 36350 / 1491825
[B] 15625 / 1491825
...
[E] 562500 / 1491825

So in the end we have something like that:

Array (
    [A] 0.0243
    [B] 0.1047
    ...
    [E] 0.3770
)

I thought in something like that:

array_walk($result, create_function('&$v,$k', '$v = array_sum($v) / count($v);'));

but then I realised that it's not correct because the first value will be divided only by how many times A occurs, the second by B's ocurrences, etc.

So we would have:

Array (
    [A] => 36350  / 3 = 12116.666666667
    [B] => 15625  / 1 = 15625
    [C] => 265625 / 2 = 132812.5
    [D] => 611725 / 2 = 305862.5
    [E] => 562500 / 1 = 562500
)

What I'm searching is a kind of weighted arithmetic mean of the grouped values of the subarrays.

I would appreciate if someone could help me finding the answer to this problem.

Many thanks in advance.

If I understand you correctly, you'd need to calculate the sum of squares before looping/walking the array. To access it inside the callback function you could use "use" in modern php (or "global" inside the function before php5.3)

// $array = your data

$result = array(); // grouped sum of squares
foreach ( $array as list( $key, $value ) ) {
  $result[$key] += $value*value;
}

$ss = array_sum(array_values($result)); // sum of squares

// array_map preserves the keys
$means = array_map(function($value) use ($ss) {return $value/$ss;}, $result);

(I absolutely haven't tested this. I think replacing the last line with something like

array_walk($result, create_function('&$v,$k', 'global $ss; $v = $v/$ss;'));

might also work)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM