How do you handle time-series that span weekends and non-work hours
I am working on a class that is going to contain objects with a time stamp and multiple measurements. These measurements are usually ta开发者_Python百科ken from 08:00 and until 16:00 every weekday, but needs to be flexible. Now, what I want is to be able to do is specify a time-interval, let's say 1 hour, and get the average. Something like myArrayList.getAvrageHeight(), and have this return the the average height from all the measurements of the last hour. I plan on keeping only the needed entries in my list, and remove those that are "timed out".
Doing this within the same day is quite straight-forward. But I would like, that when I call this method at 08.15 on Tuesday morning, myArrayList will contain 45minutes worth of data from Monday, and 15 Minutes worth of data from Tuesday.
One of my biggest constrains is that the measurements come in at arbitrary intervals, anything from 1 minute, and down to multiple times per second.
So far I got this for computing the averages every time a measurement is added:
protected void computeAvrages() {
averageWeight = 0;
averageSpeed = 0;
averageHeight = 0;
for (int i = 0; i < super.size(); i++) {
averageWeight += super.get(i).getWeight();
averageSpeed += super.get(i).getSpeed();
averageHeight += super.get(i).getHeight();
}
averageWeight = averageWeight/super.size();
averageSpeed = averageSpeed/super.size();
averageHeight = averageHeight/super.size();
}
My objects, look like this:
public class Car {
double weight;
double speed;
double height;
int timeStamp;
public Car(int timeStamp, double weight, double speed, double height) {
this.timeStamp = timeStamp;
this.weight = weight;
this.speed = speed;
this.height = height;
}
public double getWeight() {
return weight;
}
public double getSpeed() {
return speed;
}
public double getHeight() {
return height;
}
public double getTimeStamp() {
return timeStamp;
}
}
myArrayList is sorted on timeStamp in ascending order (I can use binary search on this list), and the amount of records I am planning on keeping will be from 1.000 -> 500.000 depending on traffic (about 3 cars per second for a week) The time-interval is kept as seconds, so when I specify 1 hour, I store it as 3600.
When I call myArrayList.add(aCar), computeAvrages get called, but what I wonder is the following:
- How should I handle the change of Monday -> Tuesday, and from Friday to Monday?
- I am currently storing start and stop times as startHour, startMinute, stopHour and stopMinute for simplicity, how would you have stored these time-references?
This problem might be to complex for stackoverflows question->answer type, but I'll try and make it simpler:
You are looking at a highway. Cars are passing by. Every car that passes by gets recorded with Weight, Height and Speed. Now, I want to be able to specify a time of day (i.e. 08:00 until 16:00) that interests me. Only cars that pass by during the work week is interesting (aka Monday -> Friday) I would only store cars passing by in this period, but I still get notified about cars that pass by outside of this timeframe.
I then want to compute a 1 Hour average of cars passing by within my timeframe. But at 08:15 on Tuesday I am not interested in only getting the average of the last 15 minutes, but I want the average of the last 45 minutes on Monday combined with the first 15 of Tuesday. So my questions above apply.
Your question is so complex that I (and many others) have more questions rather than answers. Anyways here is my two cents looking at the last two paragraphs of your question.
I would use the following classes:
- class
CarEvent
with three properties -wight, height, speed
- class
EventTimeStamp
with two properties -Date, ts
. ts is of type short with range 0800 to 1600. The class should have two methods -subtract(int days, int hours)
andadd(int days,int hours)
both returning another instance of EventTimeStamp. - class
TrafficLog
that holds all the CarEvents in aLinkedListMap
. A LinkedListMap is Map that allows sequential access too so that you can do binary search. The key to the map should be an instance of EventTimeStamp
With this data-structure, you can implement the analytical methods that you desire on the TrafficLog class. For example, to get the average:
public float getAverageTraffic(EventTimeStamp startDate, int durationHours)
{
EventTimeStamp startEventTS = startDate.subtract(0,durationHours);
CarEvent startEvent = eventList.get(startEventTS); //there might not be an event at exactly this point. So some tolerance have to be built in to this.
CarEvent endEvent = eventList.get(startDate);
return getAverage(startEvent,endEvent);//the two params are part of a linked list, so you can iterate and compute the average.
}
So, if I understand correctly... From 15:15 to 16:15 you get the average: 2. From 8:15 to 9:15 you get the average: 3.
You want to take the time from 16:00 to 16:15 and include it in the average time from 8:15 to 9:00.
Is this a programming problem or a math problem? Because if it's a math problem, it seems you should take (15/60) * 2 + (45/60) * 3 to get your morning average (from 8:00 to 9:00).
But, you'd want to do this every hour, not just the hours separating days. If your sample was from 8:30 to 9:30 and from 9:30 to 10:30, you should probably average every sample together.
Divide the total number of entries (in the time period) by the total time period.
Using your example: If it is 8:15 on Tuesday morning. And you want the last 15 minutes plus the last 45 minutes from the day before to complete an average for that hour. (Which is really strange by the way), then take the data from the last 45 minutes of the day before and sum it with the last 15 minutes for your average.
As far as data structures are concerned, then your "real-time" average, would hold an hour of values. As a minute within your time-period passed you would be adding data on one side and removing from the other side. This would allow you to have an hour that might span between two days.
精彩评论