#python #pandas #dataframe
#python #панды #фрейм данных
Вопрос:
У меня есть две функции:
- Сначала (z_score) для вычисления скользящих значений z-score с учетом столбца df
- Второй (z_score_cum) для вычисления кумулятивного z-score без предвзятости
# rolling z_score
def z_score(df, window):
val_column = df.columns[0]
col_mean = df[val_column].rolling(window=window).mean()
col_std = df[val_column].rolling(window=window).std()
df['zscore' '_' str(window) 'D'] = (df[val_column] - col_mean)/col_std
return df
# cumulative z_score
def z_score_cum(data_frame):
# calculating length of original data frame to standardize
len_ = len(data_frame)
# storing column name amp; making a copy of data frame
val_column = data_frame.columns[0]
data_frame_standardized_final = data_frame.copy()
# calculating statistics
data_frame_standardized_final['mean_past'] = [np.mean(data_frame_standardized_final[val_column][0:lv 1]) for lv in range(0,len_)]
data_frame_standardized_final['std_past'] = [np.std(data_frame_standardized_final[val_column][0:lv 1]) for lv in range(0,len_)]
data_frame_standardized_final['z_score_cum'] = (data_frame_standardized_final[val_column] - data_frame_standardized_final['mean_past']) / data_frame_standardized_final['std_past']
return data_frame_standardized_final[['z_score_cum']]
Я хотел бы каким-то образом объединить эти две функции в одну функцию z-score, чтобы, независимо от того, передаю ли я time window в качестве параметра, он вычислял бы z-score на основе window и, кроме того, будет содержать один столбец с кумулятивным z-score. В настоящее время я создаю список временных окон (здесь в днях), которые я передаю в цикле при вызове функции и присоединении к этому дополнительному столбцу отдельно, что, на мой взгляд, не является оптимальным способом обработки.
d_list = [n * 21 for n in range(1,13)]
df_zscore = df.copy()
for i in d_list:
df_zscore = z_score(df_zscore, i)
df_zscore_cum = z_score_cum(df)
df_z_scores = pd.concat([df_zscore, df_zscore_cum], axis=1)
Ответ №1:
В конце концов, я сделал это таким образом:
def calculate_z_scores(self, list_of_windows, freq_flag='D'):
"""
Calculates rolling z-scores and cumulative z-scores based on given list
of time windows
Parameters
----------
list_of_windows : list
a list of time windows.
freq_flag : string
frequency flag. The default is 'D' (daily)
Returns
-------
data frame
a data frame with calculated rolling amp; cumulative z-score.
"""
z_scores_data_frame = self.original_data_frame.copy()
# get column with values (1st column)
val_column = z_scores_data_frame.columns[0]
len_ = len(z_scores_data_frame)
# calculating statistics for cumulative_zscore
z_scores_data_frame['mean_past'] = [np.mean(z_scores_data_frame[val_column][0:lv 1]) for lv in range(0,len_)]
z_scores_data_frame['std_past'] = [np.std(z_scores_data_frame[val_column][0:lv 1]) for lv in range(0,len_)]
z_scores_data_frame['zscore_cum'] = (z_scores_data_frame[val_column] - z_scores_data_frame['mean_past']) / z_scores_data_frame['std_past']
# taking care of rolling z_scores
for i in list_of_windows:
col_mean = z_scores_data_frame[val_column].rolling(window=i).mean()
col_std = z_scores_data_frame[val_column].rolling(window=i).std()
z_scores_data_frame['zscore' '_' str(i) freq_flag] = (z_scores_data_frame[val_column] - col_mean)/col_std
cols_to_leave = [c for c in z_scores_data_frame.columns if 'zscore' in c]
self.z_scores_data_frame = z_scores_data_frame[cols_to_leave]
return self.z_scores_data_frame
Просто примечание: это мой метод класса, но после незначительных изменений его можно использовать как отдельную функцию.