I have a df and list of dictionary as shown below.
df:
Date t_factor
2020-02-01 5
2020-02-02 2
Define a function time_objective
which takes arguments as dataframe
and param_obj_list
and returns the dataframe with new column added. Here we have used Series.between
to create a boolean mask
and using boolean indexing
with this mask, fill the values according to the requirements:
def time_objective(df, param_obj_list):
df['new_col'] = np.nan
for d in param_obj_list:
if 'from' not in d or 'to' not in d \
or d['from'] == 0 or d['to'] == 0:
continue
if len(d['coef']) != 6:
print('Exception: Coefficients index do not match')
return df
a0, a1, a2, a3, a4, a5 = d['coef']
start = pd.Timestamp(d['from']).strftime('%Y-%m-%d')
end = pd.Timestamp(d['to']).strftime('%Y-%m-%d')
T = df['Date'].sub(pd.Timestamp(start)).dt.days
mask = df['Date'].between(start, end, inclusive=True)
if d['type'] == 'df_first':
df.loc[mask, 'new_col'] = df['t_factor']
elif d['type'] == 'quadratic':
df.loc[mask, 'new_col'] = a0 + a1 * T + a2 * (T)**2 + df['new_col'].ffill()
elif d['type'] == 'linear':
df.loc[mask, 'new_col'] = a0 + a1 * T + df['new_col'].ffill()
elif d['type'] == 'polynomial':
df.loc[mask, 'new_col'] = a0 + a1*(T) + a2*(T)**2 + a3 * \
(T)**3 + a4*(T)**4 + a5*(T)**5 + df['new_col'].ffill()
return df
Result:
Date t_factor new_col
0 2020-02-01 5 5.0
1 2020-02-02 23 23.0
2 2020-02-03 14 14.1
3 2020-02-04 23 14.3
4 2020-02-05 23 14.7
5 2020-02-06 23 15.4
6 2020-02-07 30 15.5
7 2020-02-08 29 15.6
8 2020-02-09 100 15.7
9 2020-02-10 38 15.9
10 2020-02-11 38 16.4
11 2020-02-12 38 22.1
12 2020-02-13 70 52.2
13 2020-02-14 70 152.3