¿Cuál es la manera más rápida repetidamente volver a muestrear unicc datos de la misma forma desde horaria anual en python

0

Pregunta

¿Cuál es la manera más rápida repetidamente volver a muestrear unicc datos de la misma forma?

Problema: tengo 30 años de una hora de unicc que quiero volver a muestrear anual y por año calendario (remuestrear la regla 'COMO'). Necesito encontrar la media en cada año y la suma. No faltan horas. Entonces necesitamos para hacer esto más de 10.000 veces. Para el guión que estoy escribiendo, este remuestreo de paso se lleva por lejos la mayor parte del tiempo y es el factor limitante con respecto a la optimización del tiempo de ejecución. Debido a los años bisiestos, uno no puede volver a muestrear por una constante de 8760 horas como cada cuarto año ha 8784 horas.

Ejemplo de código:

import pandas as pd
import numpy as np
import time

hourly_timeseries = pd.DataFrame(
    index=pd.date_range(
    pd.Timestamp(2020, 1, 1, 0, 0),
    pd.Timestamp(2050, 12, 31, 23, 30),
    freq="60min")
)
hourly_timeseries['value'] = np.random.rand(len(hourly_timeseries))
# Constraints imposed by wider problem:
# 1. each hourly_timeseries is unique
# 2. each hourly_timeseries is the same shape and has the same datetimeindex
# 3. a maximum of 10 timeseries can be grouped as columns in dataframe
start_time = time.perf_counter()
for num in range(100): # setting as 100 so it runs faster, this is 10,000+ in practice
    yearly_timeseries_mean = hourly_timeseries.resample('AS').mean() # resample by calendar year
    yearly_timeseries_sum = hourly_timeseries.resample('AS').sum()
finish_time = time.perf_counter()
print(f"Ran in {start_time - finish_time:0.4f} seconds")
>>> Ran in -3.0516 seconds

Las soluciones que me han explorado:

  1. He hecho algunas mejoras en la velocidad mediante la agregación de múltiples unicc en un dataframe y remuestreo de ellos al mismo tiempo; sin embargo, debido a las restricciones de la puesta en marcha de un problema mayor, estoy de problemas, estoy limitado a 10 unicc en cada dataframe. Por lo tanto, el problema sigue en pie: ¿hay una manera de acelerar drásticamente el remuestreo de unicc de datos si usted sabe la forma de la matriz va a ser siempre el mismo?
  2. También he mirado en el uso de numba pero esto no hace que los pandas funciones más rápido.

Posibles soluciones razonables, pero no puedo encontrar después de investigar:

  1. remuestrear la matriz 3D de unicc de datos con numpy
  2. Caché el índice que se vuelven a muestrear y entonces de alguna manera hacer cada remuestrear después de la primera remuestrear mucho más rápido

Gracias por tu ayuda :)

1

Mejor respuesta

0

Como escribí en el comentario, he preparado índices para cada año y se utiliza para calcular la suma mucho por cada año más rápido.

El próximo que me quita innecesario el cálculo de la suma a decir de nuevo, en lugar de calcular la media como sum/length_of_indices para cada año.

Para N=1000 su ~9x más rápido

import pandas as pd
import numpy as np
import time

hourly_timeseries = pd.DataFrame(
    index=pd.date_range(
    pd.Timestamp(2020, 1, 1, 0, 0),
    pd.Timestamp(2050, 12, 31, 23, 30),
    freq="60min")
)
hourly_timeseries['value'] = np.random.rand(len(hourly_timeseries))
# Constraints imposed by wider problem:
# 1. each hourly_timeseries is unique
# 2. each hourly_timeseries is the same shape and has the same datetimeindex
# 3. a maximum of 10 timeseries can be grouped as columns in dataframe
start_time = time.perf_counter()
for num in range(100): # setting as 100 so it runs faster, this is 10,000+ in practice
    yearly_timeseries_mean = hourly_timeseries.resample('AS').mean() # resample by calendar year
    yearly_timeseries_sum = hourly_timeseries.resample('AS').sum()
finish_time = time.perf_counter()
print(f"Ran in {finish_time - start_time:0.4f} seconds")


start_time = time.perf_counter()
events_years = hourly_timeseries.index.year
unique_years = np.sort(np.unique(events_years))
indices_per_year = [np.where(events_years == year)[0] for year in unique_years]
len_indices_per_year = np.array([len(year_indices) for year_indices in indices_per_year])
for num in range(100):  # setting as 100 so it runs faster, this is 10,000+ in practice
    temp = hourly_timeseries.values
    yearly_timeseries_sum2 = np.array([np.sum(temp[year_indices]) for year_indices in indices_per_year])
    yearly_timeseries_mean2 = yearly_timeseries_sum2 / len_indices_per_year

finish_time = time.perf_counter()
print(f"Ran in {finish_time - start_time:0.4f} seconds")
assert np.allclose(yearly_timeseries_sum.values.flatten(), yearly_timeseries_sum2)
assert np.allclose(yearly_timeseries_mean.values.flatten(), yearly_timeseries_mean2)
Ran in 0.9950 seconds
Ran in 0.1386 seconds
2021-11-21 21:00:47

En otros idiomas

Esta página está en otros idiomas

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Slovenský
..................................................................................................................