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:
b = datetime.datetime(self.year, self.seasons[p][2],
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(
tmp_df[tmp_df['period'] == p[:-1]], time_df[a:b],
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):
input_profiles = {}
for input_profile_name, input_profile_config in input_profile_dict.items():
if input_profile_config[1] == 'generate':
profile = generate_profile(input_profile_config[0], input_profile_config[2:], input_profiles, t_start,
t_horizon, t_step)
profile = generate_profile(input_profile_config[0], input_profile_config[2:], input_profiles, t_start, t_horizon, t_step)
elif input_profile_config[1] == 'modify':
profile = modify_profile(input_profile_config[0], input_profile_config[2:], input_profiles, t_start,
t_horizon, t_step)
profile = modify_profile(input_profile_config[0], input_profile_config[2:], input_profiles, t_start, t_horizon, t_step)
else:
profile = pd.read_csv(input_profile_config[1], index_col = 0)
try:
......@@ -56,8 +54,7 @@ def process_input_profiles(input_profile_dict, t_start, t_horizon, t_step):
phi = 52.21
psi_f = 0
beta = 30
input_profile = generate_g_t_series(input_profile, beta, psi_f, phi, lambda_st, lambda_1, t_start,
t_horizon, t_step)
input_profile = generate_g_t_series(input_profile, beta, psi_f, phi, lambda_st, lambda_1, t_start, t_horizon, t_step)
input_profile = input_profile.squeeze()
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
if profile_type == 'elec_demand':
profiles = []
for year in years:
profile = ElectricalDemand(year).get_profile(parameters[0], 'h0',
True) # True: with smoothing function for household profiles, False: no smoothing function for household profiles
profile = ElectricalDemand(year).get_profile(parameters[0], 'h0', 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')
profiles.append(profile)
timeseries = pd.concat(profiles)
......@@ -137,7 +133,9 @@ def modify_profile(mod_type: str, parameters, input_profiles, t_start, t_horizon
season_offset = parameters[2],
start = t_start,
model_path = parameters[3],
new=parameters[4], mod_period=365, save=parameters[5])
new = parameters[4],
mod_period = 365,
save = parameters[5])
return profile
else:
raise Exception("Modification for mod type " + str(mod_type) + " is not implemented!")
import numpy as np
import copy as cp
import pandas as pd
import math
# ----------------------------------------------------------------------------------------------------------------------
......@@ -13,84 +14,60 @@ class Predictor:
Parameters
----------
time_series:
The original time series that should be used for predictions.
profile:
The original profile that should be used for predictions.
name: str
Does not have to be unique, should be used so that the nature of the time series can be identified.
method: str
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"):
self.profile = time_series
def __init__(self, profile, type: str, method: str, t_step: float):
self.profile = profile
self.type = type
self.method = method
def rh_update(self, time_steps_rh, time_steps_fix):
"""
Selects the correct prediction method based on the selected prediction method.
Parameters
----------
time_steps_rh:
Series of time steps covering the entire horizon
time_steps_fix:
Series of time steps covering the fix part of the horizon, i.e. the part that should not be predicted.
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))
self.t_step = t_step
def predict(self, time_steps):
if self.method == "perfect_foresight":
return self.profile[time_steps]
elif self.method == "time_forward":
if 0 in time_steps:
print('Requested time forward prediction for time steps that include the first time step! Using original data for the first time step.')
return pd.Series(self.profile[time_steps[0]], index = time_steps)
else:
return pd.Series(self.profile[time_steps[0]] - 1, index = time_steps)
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":
return same_as_last_week(time_steps_rh, time_steps_fix, cp.deepcopy(self.profile))
elif self.method == "perfect_foresight":
return perfect_foresight(time_steps_rh, time_steps_fix, cp.deepcopy(self.profile))
time_steps_per_week = int(7 * 24 / self.t_step)
if time_steps[0] - time_steps_per_week < 0:
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:
# Default: Time Forward
return time_forward(time_steps_rh, time_steps_fix, cp.deepcopy(self.profile))
def get_profile(self):
"""
Returns a copy of the original time series stored in the predictor.
Returns
-------
Copy of the original time series.
"""
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
previous_week_data = np.array(self.profile[time_steps[0] - len(time_steps_per_week):time_steps[0]])
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)
prediction = pd.Series(0.0, index = time_steps)
for start, end in weeks_in_prediction:
prediction[start:end] = previous_week_data[0:end - start]
return prediction
else:
return self.profile[time_steps]
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment