Skip to content
Snippets Groups Projects
Commit a83e46cf authored by Christoph von Oy's avatar Christoph von Oy
Browse files

Merge branch 'dev_cvo_predictor_fix' into 'main'

Fixes

See merge request focus/tooling!15
parents 510cb9ad 1276d844
No related branches found
No related tags found
No related merge requests found
...@@ -163,16 +163,6 @@ class ElectricalDemand: ...@@ -163,16 +163,6 @@ class ElectricalDemand:
b = datetime.datetime(self.year, self.seasons[p][2], b = datetime.datetime(self.year, self.seasons[p][2],
self.seasons[p][3], 23, 59) self.seasons[p][3], 23, 59)
# Old Version
# --------------------------------------------------------
# new_df.update(pd.DataFrame.merge(
# tmp_df[tmp_df['period'] == p[:-1]], time_df[a:b],
# left_on=left_cols, right_on=right_cols,
# how='inner', left_index=True).sort_index().drop(
# ['hour_of_day'], 1))
# --------------------------------------------------------
# New Version
# Tested with pandas version 1.3.1
new_df.update(pd.DataFrame.merge( new_df.update(pd.DataFrame.merge(
tmp_df[tmp_df['period'] == p[:-1]], time_df[a:b], tmp_df[tmp_df['period'] == p[:-1]], time_df[a:b],
left_on=left_cols, right_on=right_cols, how='inner').sort_values( left_on=left_cols, right_on=right_cols, how='inner').sort_values(
......
...@@ -33,11 +33,9 @@ def process_input_profiles(input_profile_dict, t_start, t_horizon, t_step): ...@@ -33,11 +33,9 @@ def process_input_profiles(input_profile_dict, t_start, t_horizon, t_step):
input_profiles = {} input_profiles = {}
for input_profile_name, input_profile_config in input_profile_dict.items(): for input_profile_name, input_profile_config in input_profile_dict.items():
if input_profile_config[1] == 'generate': if input_profile_config[1] == 'generate':
profile = generate_profile(input_profile_config[0], input_profile_config[2:], input_profiles, t_start, profile = generate_profile(input_profile_config[0], input_profile_config[2:], input_profiles, t_start, t_horizon, t_step)
t_horizon, t_step)
elif input_profile_config[1] == 'modify': elif input_profile_config[1] == 'modify':
profile = modify_profile(input_profile_config[0], input_profile_config[2:], input_profiles, t_start, profile = modify_profile(input_profile_config[0], input_profile_config[2:], input_profiles, t_start, t_horizon, t_step)
t_horizon, t_step)
else: else:
profile = pd.read_csv(input_profile_config[1], index_col = 0) profile = pd.read_csv(input_profile_config[1], index_col = 0)
try: try:
...@@ -56,8 +54,7 @@ def process_input_profiles(input_profile_dict, t_start, t_horizon, t_step): ...@@ -56,8 +54,7 @@ def process_input_profiles(input_profile_dict, t_start, t_horizon, t_step):
phi = 52.21 phi = 52.21
psi_f = 0 psi_f = 0
beta = 30 beta = 30
input_profile = generate_g_t_series(input_profile, beta, psi_f, phi, lambda_st, lambda_1, t_start, input_profile = generate_g_t_series(input_profile, beta, psi_f, phi, lambda_st, lambda_1, t_start, t_horizon, t_step)
t_horizon, t_step)
input_profile = input_profile.squeeze() input_profile = input_profile.squeeze()
input_profile.set_axis(list(range(t_horizon)), inplace = True) input_profile.set_axis(list(range(t_horizon)), inplace = True)
...@@ -72,8 +69,7 @@ def generate_profile(profile_type, parameters, input_profiles, t_start, t_horizo ...@@ -72,8 +69,7 @@ def generate_profile(profile_type, parameters, input_profiles, t_start, t_horizo
if profile_type == 'elec_demand': if profile_type == 'elec_demand':
profiles = [] profiles = []
for year in years: for year in years:
profile = ElectricalDemand(year).get_profile(parameters[0], 'h0', profile = ElectricalDemand(year).get_profile(parameters[0], 'h0', True) # True: with smoothing function for household profiles, False: no smoothing function for household profiles
True) # True: with smoothing function for household profiles, False: no smoothing function for household profiles
profile = profile.resample(str(t_step) + 'H').mean().interpolate('linear') profile = profile.resample(str(t_step) + 'H').mean().interpolate('linear')
profiles.append(profile) profiles.append(profile)
timeseries = pd.concat(profiles) timeseries = pd.concat(profiles)
...@@ -137,7 +133,9 @@ def modify_profile(mod_type: str, parameters, input_profiles, t_start, t_horizon ...@@ -137,7 +133,9 @@ def modify_profile(mod_type: str, parameters, input_profiles, t_start, t_horizon
season_offset = parameters[2], season_offset = parameters[2],
start = t_start, start = t_start,
model_path = parameters[3], model_path = parameters[3],
new=parameters[4], mod_period=365, save=parameters[5]) new = parameters[4],
mod_period = 365,
save = parameters[5])
return profile return profile
else: else:
raise Exception("Modification for mod type " + str(mod_type) + " is not implemented!") raise Exception("Modification for mod type " + str(mod_type) + " is not implemented!")
import numpy as np import numpy as np
import copy as cp import pandas as pd
import math
# ---------------------------------------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------------------------------------
...@@ -13,84 +14,60 @@ class Predictor: ...@@ -13,84 +14,60 @@ class Predictor:
Parameters Parameters
---------- ----------
time_series: profile:
The original time series that should be used for predictions. The original profile that should be used for predictions.
name: str name: str
Does not have to be unique, should be used so that the nature of the time series can be identified. Does not have to be unique, should be used so that the nature of the time series can be identified.
method: str method: str
Name of the prediction method to be used. The default method is "same_as_last_day". Name of the prediction method to be used. The default method is "same_as_last_day".
""" """
def __init__(self, time_series, type: str, method: str = "same_as_last_day"): def __init__(self, profile, type: str, method: str, t_step: float):
self.profile = time_series self.profile = profile
self.type = type self.type = type
self.method = method self.method = method
self.t_step = t_step
def rh_update(self, time_steps_rh, time_steps_fix):
""" def predict(self, time_steps):
Selects the correct prediction method based on the selected prediction method. if self.method == "perfect_foresight":
return self.profile[time_steps]
Parameters elif self.method == "time_forward":
---------- if 0 in time_steps:
time_steps_rh: print('Requested time forward prediction for time steps that include the first time step! Using original data for the first time step.')
Series of time steps covering the entire horizon return pd.Series(self.profile[time_steps[0]], index = time_steps)
time_steps_fix: else:
Series of time steps covering the fix part of the horizon, i.e. the part that should not be predicted. return pd.Series(self.profile[time_steps[0]] - 1, index = time_steps)
Returns
-------
The original time series after applying the prediction method.
"""
if self.method == "time_forward":
return time_forward(time_steps_rh, time_steps_fix, cp.deepcopy(self.profile))
elif self.method == "same_as_last_day": elif self.method == "same_as_last_day":
return same_as_last_day(time_steps_rh, time_steps_fix, cp.deepcopy(self.profile)) time_steps_per_day = int(24 / self.t_step)
if time_steps[0] - time_steps_per_day < 0:
print('Requested same as last day prediction for time steps that include the first day. Using original data for the first day.')
previous_day_data = np.zeros(time_steps_per_day)
previous_day_data[:time_steps_per_day - time_steps[0]] = self.profile[time_steps[0]:time_steps_per_day]
previous_day_data[time_steps_per_day - time_steps[0]:] = self.profile[:time_steps[0]]
else:
previous_day_data = np.array(self.profile[time_steps[0] - len(time_steps_per_day):time_steps[0]])
days_in_prediction = [(t * time_steps_per_day, (t + 1) * time_steps_per_day) for t in range(math.ceil(len(time_steps) / time_steps_per_day))]
days_in_prediction[-1] = (days_in_prediction[-1][0], time_steps[-1] - time_steps[0] + 1)
prediction = pd.Series(0.0, index = time_steps)
for start, end in days_in_prediction:
prediction[start:end] = previous_day_data[0:end - start]
return prediction
elif self.method == "same_as_last_week": elif self.method == "same_as_last_week":
return same_as_last_week(time_steps_rh, time_steps_fix, cp.deepcopy(self.profile)) time_steps_per_week = int(7 * 24 / self.t_step)
elif self.method == "perfect_foresight": if time_steps[0] - time_steps_per_week < 0:
return perfect_foresight(time_steps_rh, time_steps_fix, cp.deepcopy(self.profile)) print('Requested same as last week prediction for time steps that include the first week. Using original data for the first week.')
previous_week_data = np.zeros(time_steps_per_week)
previous_week_data[:time_steps_per_week - time_steps[0]] = self.profile[time_steps[0]:time_steps_per_week]
previous_week_data[time_steps_per_week - time_steps[0]:] = self.profile[:time_steps[0]]
else: else:
# Default: Time Forward previous_week_data = np.array(self.profile[time_steps[0] - len(time_steps_per_week):time_steps[0]])
return time_forward(time_steps_rh, time_steps_fix, cp.deepcopy(self.profile)) weeks_in_prediction = [(t * time_steps_per_week, (t + 1) * time_steps_per_week) for t in range(math.ceil(len(time_steps) / time_steps_per_week))]
weeks_in_prediction[-1] = (weeks_in_prediction[-1][0], time_steps[-1] - time_steps[0] + 1)
def get_profile(self):
""" prediction = pd.Series(0.0, index = time_steps)
Returns a copy of the original time series stored in the predictor. for start, end in weeks_in_prediction:
prediction[start:end] = previous_week_data[0:end - start]
Returns return prediction
------- else:
Copy of the original time series. return self.profile[time_steps]
"""
return cp.deepcopy(self.profile)
def time_forward(time_steps_rh, time_steps_fix, reference):
reference.loc[list(set(time_steps_rh) - set(time_steps_fix))] = reference[time_steps_fix[-1]]
return reference
def same_as_last_day(time_steps_rh, time_steps_fix, reference):
# Assumes that one time step is equal to 1h, should this change this code needs to be adjusted
# Get list of time steps that need to be predicted. time_steps_rh \ time_steps_fix
pred_steps = np.array(list(set(time_steps_rh) - set(time_steps_fix)))
# Remove all pred_steps that are below 24, because no data from 24h earlier is present in the data.
pred_steps = pred_steps[np.abs(pred_steps) > 23]
# Replace all pred_steps with its data from 24 hours earlier
reference.loc[pred_steps] = reference[pred_steps - 24].tolist()
return reference
def same_as_last_week(time_steps_rh, time_steps_fix, reference):
# Assumes that one time step is equal to 1h, should this change this code needs to be adjusted
# Get list of time steps that need to be predicted. time_steps_rh \ time_steps_fix
pred_steps = np.array(list(set(time_steps_rh) - set(time_steps_fix)))
# Remove all pred_steps that are below 168, because no data from one week earlier is present in the data.
pred_steps = pred_steps[np.abs(pred_steps) > 167]
# Replace all pred_steps with its data from 7*24 hours earlier
reference.loc[pred_steps] = reference[pred_steps - 168].tolist()
return reference
def perfect_foresight(time_steps_rh, time_steps_fix, reference):
# Assume that we can perfectly "predict" the future
return reference
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment