user3010273
user3010273

Reputation: 900

Calculating average value for array with PHP?

My head is exploding with this. I can't seem to create a working solution.

I have a file in this format:

99895|35378|0.01
99895|813|-0.97
99895|771|0.29
442|833|-1.06
442|485|-0.61
442|367|-0.14
442|478|0.77
442|947|-0.07
7977|987|0.76
7977|819|0.37
7977|819|0.36
7977|653|1.16
7977|1653|1.15

I want to calculate average values from third column for each id from the first column.

This seems so easy but I can't get this to work. How do you get averages for any said id from first column?

EDIT:

Some sample code I've written before:

$file = file_get_contents("results.txt");


$file = explode("
", $file);

$howMany = count($file);

for($a = 0;$a<$howMany;$a++)
{

$row = explode("|", $file[$a]);
$id = $row[0];



$howManyAlready = count($bigTable[$id]);

$bigTable[$id][$howManyAlready] = $row[2];

}

I've added the code. So far it gets the results into an array ( with offset corresponding to its id ) But I am having trouble with how to get those results and calculate average for each id and then present it on the screen.

Upvotes: 2

Views: 20127

Answers (7)

Alexander Yancharuk
Alexander Yancharuk

Reputation: 14501

Try this:

$filename = 'results.txt';
$result = $counter = $values = array();

$file = fopen($filename, 'r') or die("Couldn't open $filename");
while ($line = fgets($file)) {
    $content = explode('|', $line);
    if (empty($content[0]) or empty($content[2]))
        continue;

    $values[$content[0]][] = (float) $content[2];
    ++$counter[$content[0]];
}

foreach ($values as $key => $value) {
    $result[$key] = array_sum($value) / $counter[$key];
}
fclose($file);

Upvotes: 1

Ripa Saha
Ripa Saha

Reputation: 2540

If You try below code

<?php
$file_content = array();
$handle = fopen("test.txt", "r");
if ($handle) {
    while (($line = fgets($handle)) !== false) {
        // process the line read.
        $line_ex = explode("|",$line);
        array_push($file_content,$line_ex);
    }
} else {
    // error opening the file.

}

echo "<pre>";
    print_r($file_content);
    echo "<pre>";
?>

then You will get below output

Array
(
[0] => Array
    (
        [0] => 99895
        [1] => 35378
        [2] => 0.01

    )

[1] => Array
    (
        [0] => 99895
        [1] => 813
        [2] => -0.97

    )

[2] => Array
    (
        [0] => 99895
        [1] => 771
        [2] => 0.29

    )

[3] => Array
    (
        [0] => 442
        [1] => 833
        [2] => -1.06

    )

[4] => Array
    (
        [0] => 442
        [1] => 485
        [2] => -0.61

    )

[5] => Array
    (
        [0] => 442
        [1] => 367
        [2] => -0.14

    )

[6] => Array
    (
        [0] => 442
        [1] => 478
        [2] => 0.77

    )

[7] => Array
    (
        [0] => 442
        [1] => 947
        [2] => -0.07

    )

[8] => Array
    (
        [0] => 7977
        [1] => 987
        [2] => 0.76

    )

[9] => Array
    (
        [0] => 7977
        [1] => 819
        [2] => 0.37

    )

[10] => Array
    (
        [0] => 7977
        [1] => 819
        [2] => 0.36

    )

[11] => Array
    (
        [0] => 7977
        [1] => 653
        [2] => 1.16

    )

[12] => Array
    (
        [0] => 7977
        [1] => 1653
        [2] => 1.15
    )

)

For determining average value from third column of corresponding first column - I am researching on it. When I will be done I'll put it here.

Upvotes: 1

Albzi
Albzi

Reputation: 15609

Here some something I've just written.

In my example it takes it from a string.

<?php
$test1 = "";
$test2 = "";
$count1 = 0;
$count2 = 0;
$string = "99895|35378|0.01
99895|813|-0.97
99895|771|0.29
442|833|-1.06
442|485|-0.61
442|367|-0.14
442|478|0.77
442|947|-0.07
7977|987|0.76
7977|819|0.37
7977|819|0.36
7977|653|1.16
7977|1653|1.15";

$d = explode("\n", $string);
foreach ($d as $k => $v)
{
    $d2 = explode("|", $v);

    if ($d2[0] == '99895'){
        $count1++;
        $test1 += $d2[2];
    }
    if ($d2[0] == '442'){
        $count2++;
        $test2 += $d2[2];
    }
}

$result1 = $test1 / $count1;
$result2 = $test2 / $count2;

echo $result1. " <br> ". $result2;

I don't know how well this will work as I don't know if the values are set or not.

Upvotes: 1

Theox
Theox

Reputation: 1363

You can try doing this :

$file = file_get_contents("results.txt");
$file = explode("
", $file);

$valuesPerID = Array();

foreach($file as $row)
{

    $row_array = explode("|", $row);

    $id = $row_array[0];

    if(!array_key_exists($id, $valuesPerID))
    {
        $valuesPerID[$id] = Array();
    }

    $valuesPerID[$id][] = $row_array[2];

}

Now in the $valuesPerID array, you'll have all your ID as keys, and for each ID, all the values associated with the said ID. They you can easily calculate the average of these values !

Upvotes: 1

Anthony Sterling
Anthony Sterling

Reputation: 2441

This should put you on the right track.

<?php
$values = array();

foreach (file('file.txt') as $line) {
    list($id, $thingymabob, $value) = explode('|', $line);

    if ( ! array_key_exists($id, $values)) {
        $values[ $id ] = array();
    }

    array_push($values[ $id ], $value);
}

foreach ($values as $id => $value) {
    printf(
        "%d has an average of %f\n",
        $id,
        array_sum($value) / count($value)
    );
}

Upvotes: 1

Something like this should definitely work..

<?php
$arr=array();
$arrv=array_filter(file('myfile.txt'),'strlen');
foreach($arrv as $v)
{
    array_push($arr,@array_pop(explode('|',$v)));
}
echo $avg = array_sum($arr)/count($arr);

Upvotes: 5

user1902830
user1902830

Reputation:

You can use array mapping to assign value and id. For example (assume that you have handled the text):

<?php
    $data = array("99895|35378|0.01",
        "99895|813|-0.97",
        "99895|771|0.29",
        "442|833|-1.06",
        "442|485|-0.61",
        "442|367|-0.14",
        "442|478|0.77",
        "442|947|-0.07",
        "7977|987|0.76",
        "7977|819|0.37",
        "7977|819|0.36",
        "7977|653|1.16",
        "7977|1653|1.15");

    $bucket = array();
    $count = array();
    foreach($data as $line) {
        list($id, $what_s_this, $number) = explode("|", $line);
        $count[$id]++;
        $bucket[$id]+= (float)$number;
    }

    foreach($bucket as $id => $sum) {
        echo "id:". $id. ", average". $sum / $count[$id]. "\n";
    }

Upvotes: 1

Related Questions