1

I'm using a series of MySQL queries to pull back calculations stored by date for graphing via the Flot library. After the calculations are done, the echoed material looks like this (using UNIX timestamp dates):

Item 1: 
        [
            [1159765200000,-117.875], 
            [1159851600000,-117.25], 
            [1159938000000,-120.625], 
            [1160024400000,-122.125], 
            [1160110800000,-118.125], 
            [1160370000000,-121.125], 
            [1160456400000,-123.375], 
            [1160542800000,-115.625], 
            [1160629200000,-117.75], 
            [1160715600000,-112.75], 
            [1160974800000,-125.25], 
            [1161061200000,-135], 
            [1161147600000,-138.375], 
            [1161234000000,-137], 
            [1161320400000,-136.25], 
            [1161579600000,-139.875], 
            [1161666000000,-146.625], 
            [1161752400000,-143.625], 
            [1161838800000,-150.25], 
            [1161925200000,-152.875], 
            [1162188000000,-151.75], 
            [1162274400000,-149.75]
        ]


Item 2: 
        [
            [1104732000000,47.3913043478], 
            [1104818400000,45.5072463768], 
            [1104904800000,45.5797101449], 
            [1104991200000,45.115942029], 
            [1105077600000,44.1739130435], 
            [1105336800000,44.5362318841], 
            [1105423200000,45.9565217391], 
            [1105509600000,45.9420289855], 
            [1105596000000,46.0289855072], 
            [1105682400000,46.4347826087], 
            [1106028000000,48.347826087], 
            [1106114400000,46.8695652174], 
            [1106200800000,46.4927536232], 
            [1106287200000,45.6376811594], 
            [1106546400000,44.3768115942], 
            [1106632800000,44.0579710145], 
            [1106719200000,44.5942028986], 
            [1106805600000,45.0289855072], 
            [1106892000000,45.231884058], 
            [1107151200000,46.1449275362], 
            [1107237600000,46.5942028986], 
            [1107324000000,45.5652173913], 
            [1107410400000,45], 
            [1107496800000,46.2608695652], 
            [1107756000000,45.7391304348], 
            [1107842400000,46.3333333333]
        ]

Basically I'd like to calculate the average of the second value in each pair, controlling for the date. In other words, for each date that matches in each array, print the date and the average of all the second values in each array, e.g:

[Common Date, Average of all second values]

I've looked through a number of array merging techniques but can't seem to find a workable solution.

Thanks very much for any help.

2
  • What do you mean by "each date that matches in each array?" Commented Aug 23, 2011 at 16:37
  • I mean, each item has a series of dates. For each unique date, there should be a series of corresponding values (for each item). In other words, take the values for each item and group them by date. Does that make sense? Commented Aug 23, 2011 at 16:49

2 Answers 2

1

You could construct an array indexed by date in which you put a list of all values for the date:

$byDate = array();
foreach($item1 as $row) {
    $date = sprintf('%.0f', $row[0]);
    $byDate[$date][] = $row[1];
}
foreach($item2 as $row) {
    $date = sprintf('%.0f', $row[0]);
    $byDate[$date][] = $row[1];
}

Then you can easily compute the average for each list:

foreach($byDate as $date => $values) {
    $avg = array_sum($values) / count($value);
    printf("avg for %s: %f\n", $date, $avg);
}

Or compute all averages at once:

function array_avg($array) {
    return array_sum($array) / count($array);
}
$avgByDate = array_map('array_avg', $byDate);

Try it here: http://codepad.org/1S1HrYoB

Sign up to request clarification or add additional context in comments.

6 Comments

Just remember to pass the array through ksort(), so that in case of missing values in one of the arrays your result will be correctly ordered.
I don't think the order matters
In your code it doesn't, but if Ben tries to chart it then it may.
Apparently I don't have enough "reputation" to vote you up, but thanks very much -- this was extremely helpful.
Hi Crack and or Arnaud -- how would I go about running these arrays through ksort? Indeed I am getting odd results when graphing because the numbers are out of order, however, does ksort work when you are using arrays like this? I thought it only worked for key-value type pairs
|
0

For your merge

$merged_array = array();

function merge_by_time()
{
    $passed_arrays = func_get_args();

    $merged_array = array();
    foreach($passed_arrays as $array)
        foreach($array as $value_set){
            $merged_array[$value_set[0]][] = $value_set[1];
        }
    }

    return $merged_array;
}

Usage:

$new_array = merge_by_time($array1, $array2, $array3, ...)

Then you'll have an array based on timestamp that has all associated data values contained in it. I think you can take it from here to get the averages?


Second approach

function merge_by_time_and_get_average()
{
    $passed_arrays = func_get_args();

    $merged_array = array();
    foreach($passed_arrays as $array)
        foreach($array as $value_set){
            $merged_array[$value_set[0]]['data'][] = $value_set[1];

            $merged_array[$value_set[0]]['average'] = 0;
            foreach($merged_array[$value_set[0]]['data'] as $data_point){
                $merged_array[$value_set[0]]['average'] += $data_point;
            }
            $merged_array[$value_set[0]]['average'] = $merged_array[$value_set[0]]['average']/count($merged_array[$value_set[0]]['data'])
        }
    }

    return $merged_array;
}

Then you have $array[{timestamp}]['data'] containing your data points and $array[{timestamp}]['average'] containing your average of all data points. The nested foreachs are a little messy and expensive, but you can handle it all in one function call.

4 Comments

afuzzyllama -- thank you so much for your help. What should the arrays look like for your function? Should they be "date" as the key then the second number as the value?
It should work with the items you posted. Where it is an array which contains array pairs of [timestamp, value].
Thanks -- what I meant is that I'm trying to structure how I pull the data out of the MySQL database so that the array matches the structure used in your function. Heretofore I had been just been using a while loop and echoing out the date and calculated value. Thanks again so much.
Something like SELECT timestamp, value FROM data_table WHERE ... and then use mysql-fetch-assoc. You'll have to alter my function somewhat to use your column names instead of the 0 / 1 index

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.