Quel est le moyen le plus rapide à plusieurs reprises rééchantillonnage des données timeseries de la même forme à partir d'un horaire annuel en python

0

La question

Quel est le moyen le plus rapide à plusieurs reprises rééchantillonnage des données timeseries de la même forme?

Problème: j'ai 30 ans d'un horaire timeseries que je veux ré-échantillonner chaque année et par année civile (resample règle "COMME"). J'ai besoin de trouver à la fois la moyenne de chaque année et la somme. Il n'y a aucun manque des heures. Je puis avoir besoin de faire plus de 10 000 fois. Pour le script, je suis en train d'écrire, ce rééchantillonnage étape est de loin le plus de temps et qui est le facteur limitant en ce qui concerne l'optimisation du temps d'exécution. À cause des années bissextiles, on ne peut pas rééchantillonnage par une constante 8760 heures que tous les cours de la quatrième année a 8784 heures.

Exemple de code:

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

Les Solutions que j'ai explorées:

  1. J'ai fait quelques améliorations de la vitesse par l'agrégation de plusieurs timeseries dans un dataframe et rééchantillonnage en même temps; cependant, en raison des restrictions de la mise en place de l'ensemble du problème, je suis de problèmes, je suis limité à 10 timeseries dans chaque dataframe. Par conséquent, le problème tient toujours: est-il possible d'accélérer considérablement le rééchantillonnage des données timeseries si vous connaissez la forme de la matrice sera toujours la même?
  2. J'ai aussi regardé dans l'aide de numba, mais cela ne fait pas de pandas fonctions plus rapide.

Solutions possibles dont le son est raisonnable, mais je ne trouve pas, après des recherches:

  1. rééchantillonnage d'un tableau 3D de données timeseries avec numpy
  2. Cache de l'index est en cours de ré-échantillonné, puis en quelque sorte le faire tous les rééchantillonner après la première resample beaucoup plus rapide

Merci pour votre aide :)

1

La meilleure réponse

0

Comme je l'ai écrit dans un commentaire, j'ai préparé des indices pour chaque année et de les utiliser pour calculer une somme beaucoup pour chaque année plus rapidement.

Ensuite, j'ai enlevé inutile calcul de la somme en vertu de dire encore une fois, au lieu de calculer signifie que sum/length_of_indices pour chaque année.

Pour N=1000 sa ~9x plus rapide

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

Dans d'autres langues

Cette page est dans d'autres langues

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