2011-10-21 18 views
5

Tengo una matriz numpy 3D (tiempo, X, Y) que contiene 6 series de tiempo por hora durante algunos años. (decir 5). Me gustaría crear una serie temporal muestreada que contenga 1 instancia de cada día calendario tomada al azar de los registros disponibles (5 posibilidades por día), de la siguiente manera.¿Cuál es la manera más rápida de muestrear rebanadas de matrices numpy?

  • Ene 01: 2006
  • Ene 02: 2011
  • Ene 03: 2009
  • ...

esto significa que tengo que tomar 4 valores del 01/01/2006 , 4 valores a partir del 02/01/2011, etc. Tengo una versión funcional que funciona de la siguiente manera:

  • remodelar la matriz de entrada para añadir una dimensión "año" (Time, Año, X, Y)
  • crear una matriz 365 valores de números enteros generados al azar entre 0 y 4
  • Uso np.repeat y matriz de enteros para extraer sólo los valores relevantes:

Ejemplo:

sampledValues = Variable[np.arange(numberOfDays * ValuesPerDays), sampledYears.repeat(ValuesPerDays),:,:] 

esto parece funcionar, pero me preguntaba si este es el mejor enfoque/más rápida de resolver mi problema? La velocidad es importante ya que estoy haciendo esto en un bucle, y me beneficiaría probando tantos casos como sea posible.

¿Estoy haciendo esto bien?

Gracias

EDITAR me olvidó mencionar que el conjunto de datos de entrada filtrada para eliminar el 29 de febrero para los años bisiestos.

Básicamente el objetivo de esa operación es encontrar una muestra de 365 días que coincida bien con la serie temporal a largo plazo en términos de media, etc. Si la serie temporal muestreada pasa mi prueba de calidad, quiero exportarla y comenzar de nuevo.

Respuesta

3

El año 2008 fue de 366 días, por lo tanto, no remodele.

Tenga una mirada en scikits.timeseries:

import scikits.timeseries as ts 

start_date = ts.Date('H', '2006-01-01 00:00') 
end_date = ts.Date('H', '2010-12-31 18:00') 
arr3d = ... # your 3D array [time, X, Y] 

dates = ts.date_array(start_date=start_date, end_date=end_date, freq='H')[::6] 
t = ts.time_series(arr3d, dates=dates) 
# just make sure arr3d.shape[0] == len(dates) ! 

Ahora se puede acceder a los datos t con día/mes/objetos año:

t[np.logical_and(t.day == 1, t.month == 1)] 

así por ejemplo:

for day_of_year in xrange(1, 366): 
    year = np.random.randint(2006, 2011) 

    t[np.logical_and(t.day_of_year == day_of_year, t.year == year)] 
    # returns a [4, X, Y] array with data from that day 

Juega con los atributos de t para que funcione también con los años bisiestos.

+0

¡Esto parece un enfoque prometedor! – heltonbiker

+0

Debería haberlo mencionado, pero en este caso realmente no me importan los años bisiestos, ya que eliminé todas las ocurrencias del 29 de febrero en la serie temporal de entrada. Pensé en utilizar scikits.timeseries, sin embargo, no estoy seguro de que realmente me beneficiaría en términos de velocidad. Además, es posible que desee comenzar mis días a las 6:00 o a las 12:00, así que realmente no quiero tener que crear una matriz de objetos datetime para extraer cada vez que podría usar mi matriz muestreada (rs = np .random.randint (0, np.size (años), tamaño = 365)) enseguida. ¡Pero puedo estar equivocado! – Jahfet

0

No veo una necesidad real de remodelar la matriz, ya que puede insertar la información del tamaño de año en el proceso de muestreo y dejar la matriz con su forma original.

Por ejemplo, puede generar un desplazamiento aleatorio (de 0 a 365) y elegir el sector con índice, por ejemplo, n*365 + offset.

De todos modos, no creo que su pregunta esté completa, porque no entendí muy bien lo que tiene que hacer o por qué.

+0

No sé si la operación de remodelación es necesaria o no, simplemente pensé que sería conveniente para mí, ya que básicamente puedo seleccionar qué año quiero extraer para cada día con mucha facilidad. Solo tengo que hacerlo una vez antes de ingresar al ciclo de muestreo, así que pensé que eso no afectaría el rendimiento. Agregué algunos detalles a la pregunta, con suerte comprenderás mejor lo que busco. – Jahfet

Cuestiones relacionadas