def hourly(daily_df, classes, parameters): def hourly_factors(building): # This function selects hourly factors from BGW 2006 by time and temperature class slp = pd.DataFrame(index=classes.index, columns=classes.columns) # Time includes the hour of the day times = classes.index.map(lambda x: x.strftime('%H:%M')) # For commercial buildings, time additionally includes the weekday if building == 'COM': weekdays = classes.index.map(lambda x: int(x.strftime('%w'))) times = list(zip(weekdays, times)) for column in classes.columns: slp[column] = parameters[building].lookup(times, classes.loc[:, column]) return slp buildings = daily_df.columns.get_level_values('building').unique() results = pd.concat( [upsample_df(daily_df, '60min')[building] * hourly_factors(building) for building in buildings], keys=buildings, names=['building', 'country', 'latitude', 'longitude'], axis=1 ) return results.swaplevel('building', 'country', axis=1)
def temperature(input_path, year_start, year_end, mapped_population): parameters = {'air': 't2m', 'soil': 'stl4'} t = pd.concat([ read.temperature(input_path, year_start, year_end, parameter) for parameter in parameters.values() ], keys=parameters.keys(), names=['parameter', 'latitude', 'longitude'], axis=1) t = upsample_df(t, '60min') # Temperature data is filtered by country return pd.concat([ pd.concat([ t[parameter][population.index] for population in mapped_population.values() ], keys=mapped_population.keys(), axis=1) for parameter in parameters.keys() ], keys=parameters.keys(), names=['parameter', 'country', 'latitude', 'longitude'], axis=1).apply(pd.to_numeric, downcast='float')
def hourly_water(daily_df, temperature, parameters): # For water heating, the highest temperature classes '30' is chosen # This is re-sampled to a 60-min-resolution and passed to the general hourly function classes = upsample_df( pd.DataFrame(30, index=temperature.index, columns=temperature.columns), '60min' ).astype(int).astype(str) return hourly(daily_df, classes, parameters)
def hourly_heat(daily_df, temperature, parameters): # According to BGW 2006, temperature classes are derived from the temperature data # This is re-sampled to a 60-min-resolution and passed to the general hourly function classes = upsample_df( (np.ceil(((temperature - 273.15) / 5).astype('float64')) * 5).clip(lower=-15, upper=30), '60min' ).astype(int).astype(str) return hourly(daily_df, classes, parameters)
def hourly_heat(daily_df, temperature, parameters): # According to BGW 2006, temperature classes are derived from the temperature data # This is re-sampled to a 60-min-resolution and passed to the general hourly function # MP: For each latitude,lognitude in the grid classes contains the # temperature in one of the 5 degree bands 5,10,15 etc to look up # the hourly factors to multiply by. classes = upsample_df( (np.ceil(((temperature - 273.15) / 5).astype('float64')) * 5).clip(lower=-15, upper=30), '60min' ).astype(int).astype(str) return hourly(daily_df, classes, parameters)
def temperature(input_path, year, mapped_population, interim_path, country='GB', grid='I', hour=6): file = os.path.join(interim_path, 'temperature_' + grid + country + str(year)) if os.path.isfile(file): temp_data = pd.read_pickle(file) print( 'temperature preprocessed {} already exists and is read from disk.' .format(file)) else: parameters = {'air': 't2m', 'soil': 'stl4'} t = pd.concat([ read.temperature_era5(input_path, year, hour, grid, parameter) for parameter in parameters.values() ], keys=parameters.keys(), names=['parameter', 'latitude', 'longitude'], axis=1) t = upsample_df(t, '60min') temp_data = pd.concat([ t[parameter][mapped_population.index.tolist()] for parameter in parameters.keys() ], keys=parameters.keys(), names=['parameter', 'latitude', 'longitude'], axis=1) # Write results to interim path temp_data.to_pickle(file) return temp_data
def temperature(input_path, year_start, year_end, mapped_population): parameters = {'air': 't2m', 'soil': 'stl4'} t = pd.concat([ read.temperature(input_path, year_start, year_end, parameter) for parameter in parameters.values() ], keys=parameters.keys(), names=['parameter', 'latitude', 'longitude'], axis=1) t = upsample_df(t, '60min') # Temperature data is filtered by country return pd.concat([ pd.concat([ t[parameter][population.index] for population in mapped_population.values() ], keys=mapped_population.keys(), axis=1) for parameter in parameters.keys() ], keys=parameters.keys(), names=['parameter', 'country', 'latitude', 'longitude'], axis=1).apply(pd.to_numeric, downcast='float') #%% Custom temperature # def upsample_df(df, resolution): # # The low-resolution values are applied to all high-resolution values up to the next low-resolution value # # In particular, the last low-resolution value is extended up to where the next low-resolution value would be # df = df.copy() # # Determine the original frequency # freq = df.index[-1] - df.index[-2] # # Temporally append the DataFrame by one low-resolution value # df.loc[df.index[-1] + freq, :] = df.iloc[-1, :] # dtidx = pd.date_range(str(df.index[0]),str(df.index[-1]), freq=freq) # df.index = dtidx # # Up-sample # df = df.resample(resolution).pad() # # Drop the temporal low-resolution value # df.drop(df.index[-1], inplace=True) # return df # parameters = { # 'air': 't2m', # 'soil': 'stl4' # } # t = pd.concat( # [read.temperature(input_path, year_start, year_end, parameter) for parameter in parameters.values()], # keys=parameters.keys(), names=['parameter', 'latitude', 'longitude'], axis=1 # ) # t = upsample_df(t, '60min') # # Temperature data is filtered by country # temperature = pd.concat( # [pd.concat( # [t[parameter][population.index] for population in mapped_population.values()], # keys=mapped_population.keys(), axis=1 # ) for parameter in parameters.keys()], # keys=parameters.keys(), names=['parameter', 'country', 'latitude', 'longitude'], axis=1 # ).apply(pd.to_numeric, downcast='float')