Rolling Average para calcular la intensidad de la lluvia.

Tengo algunos datos reales de lluvia registrados como la fecha y la hora, y el número acumulado de sugerencias en un medidor de lluvia con cucharón basculante. El cucharón basculante representa 0.5mm de lluvia. Quiero desplazarme por el archivo y determinar la variación en la intensidad (lluvia / tiempo) Por lo tanto, necesito un promedio móvil en varios marcos de tiempo fijos: por lo tanto, quiero acumular lluvia, hasta que se acumulen 5 minutos de lluvia y determinar la intensidad en mm / hora. Entonces, si se registra 3 mm en 5 minutos, es igual a 3/5 * 60 = 36 mm / h. la misma lluvia en 10 minutos sería 18mm / hr …

Entonces, si tengo lluvia durante varias horas, es posible que tenga que revisar a varios intervalos estándar, por ejemplo: 5, 10,15,20,25,30,45,60 minutos, etc. También se registran los datos en orden inverso en el archivo en bruto, por lo que la hora más temprana está al final del archivo y el último y último paso aparece primero después de un encabezado: Parece que … (aquí 975 – 961 = 14 puntas = 7 mm de precipitación) intensidad media 1.4 mm / hr Pero entre las 16:27 y las 16:34 967-961 = 6 puntas = 3 mm en 7 min = 27.71 mm / hora

7424 Figtree (O'Briens Rd) DATE :hh:mm Accum Tips 8/11/2011 20:33 975 8/11/2011 20:14 974 8/11/2011 20:04 973 8/11/2011 20:00 972 8/11/2011 19:35 971 8/11/2011 18:29 969 8/11/2011 16:44 968 8/11/2011 16:34 967 8/11/2011 16:33 966 8/11/2011 16:32 965 8/11/2011 16:28 963 8/11/2011 16:27 962 8/11/2011 15:30 961 

¿Alguna sugerencia?

No estoy completamente seguro de qué es lo que tiene una pregunta.

¿Sabes cómo leer el archivo? Puedes hacer algo como:

 data = [] # Empty list of counts # Skip the header lines = [line.strip() for line in open('data.txt')][2::] for line in lines: print line date, hour, count = line.split() h,m = hour.split(':') t = int(h) * 60 + int(m) # Compute total minutes data.append( (t, int(count) ) ) # Append as tuple data.reverse() 

Ya que sus datos son acumulativos, debe restar cada una de las dos entradas, aquí es donde las comprensiones de la lista de python son realmente agradables.

 data = [(t1, d2 - d1) for ((t1,d1), (t2, d2)) in zip(data, data[1:])] print data 

Ahora debemos recorrer y ver cuántas entradas hay en los últimos x minutos.

 timewindow = 10 for i, (t, count) in enumerate(data): # Find the entries that happened within the last [...] minutes withinwindow = filter( lambda x: x[0] > t - timewindow, data ) # now you can print out any kind of stats about this "within window" entries print sum( count for (t, count) in withinwindow ) 

Dado que las marcas de tiempo no vienen a intervalos regulares, debe usar la interpolación para obtener los resultados más precisos. Esto hará que la media móvil también sea más fácil. Estoy usando la clase Interpolate en esta respuesta en el siguiente código.

 from time import strptime, mktime totime = lambda x: int(mktime(strptime(x, "%d/%m/%Y %H:%M"))) with open("my_file.txt", "r") as myfile: # Skip header for line in myfile: if line.startswith("DATE"): break times = [] values = [] for line in myfile: date, time, value = line.split() times.append(totime(" ".join((date, time)))) values.append(int(value)) times.reverse() values.reverse() i = Interpolate(times, values) 

Ahora solo es cuestión de elegir los intervalos y calcular la diferencia entre los puntos finales de cada intervalo. Vamos a crear una función de generador para eso:

 def rolling_avg(cumulative_lookup, start, stop, step_size, window_size): for t in range(start + window_size, stop, step_size): total = cumulative_lookup[t] - cumulative_lookup[t - window_size] yield total / window_size 

A continuación, estoy imprimiendo el número de consejos por hora en la hora anterior con intervalos de 10 minutos:

 start = totime("8/11/2011 15:30") stop = totime("8/11/2011 20:33") for avg in rolling_avg(i, start, stop, 600, 3600): print avg * 3600 

EDIT: Hecho totime devolver un int y creó el generador rolling_avg .