Pandas: вычисление Z-показателя, чтобы избежать смещения "взгляд вперед" - PullRequest
1 голос
/ 15 февраля 2020

У меня есть данные временного ряда в кадре данных с именем "df", и мой код для вычисления z-показателя приведен ниже:

mean = df.mean()
standard_dev = df.std()
z_score = (df - mean) / standard_dev

Я хотел бы рассчитать z-показатель для каждого наблюдения используя соответствующее наблюдение и данные, которые были известны в момент записи наблюдения. т.е. я не хочу использовать стандартное отклонение и имею в виду, что он включает в себя данные, которые появляются после определенного c момента времени. Я просто хочу использовать данные из времени т, т-1, т-2 ....

Как мне это сделать?

Ответы [ 2 ]

0 голосов
/ 15 февраля 2020

Используйте .expanding() - col в качестве столбца, для которого вы хотите вычислить свою статистику (пропустите [col] в случае, если вы хотите sh, чтобы вычислить ее для всего фрейма данных):

Может потребоваться сначала отсортировать значения по столбцу времени - обозначается time_col (в случае, если он еще не отсортирован):

df=df.sort_values("time_col", axis=0)

Тогда:

df[col].sub(df[col].expanding().mean()).div(df[col].expanding().std())

Ссылка: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.expanding.html

Для данных образца:

import pandas as pd

df=pd.DataFrame({"a": list("xyzpqrstuv"), "b": [6,5,7,1,-9,0,3,5,2,8]})

df["c"]=df["b"].sub(df["b"].expanding().mean()).div(df["b"].expanding().std())

Выходы:

   a  b         c
0  x  6       NaN
1  y  5 -0.707107
2  z  7  1.000000
3  p  1 -1.425880
4  q -9 -1.677484
5  r  0 -0.281450
6  s  3  0.210502
7  t  5  0.534207
8  u  2 -0.046142
9  v  8  1.062430
0 голосов
/ 15 февраля 2020

Вы можете назначить два новых столбца, содержащие среднее и стандартное для предыдущих элементов. Здесь я предполагаю, что ваши данные временного ряда находятся в столбце «time_series_data»:

len_ = len(df)
df['mean_past'] = [np.mean(df['time_series_data'][0:lv+1]) for lv in range(len_)]
df['std_past'] = [np.std(df['time_series_data'][0:lv+1]) for lv in range(len_)]
df['z_score'] = (df['time_series_data'] - df['mean_past']) / df['std_past']

Редактировать : если вы хотите z-Score всех столбцов, вы можете определить функцию, который вычисляет z-показатель и применяет его ко всем столбцам вашего фрейма данных:

def z_score_column(column):
    len_ = len(column)
    mean = [np.mean(column[0:lv+1]) for lv in range(0,len_)]
    std =  [np.std(column[0:lv+1]) for lv in range(0,len_)]
    return [(c-m)/s for c,m,s in zip(column, mean, std)]

df = pd.DataFrame(np.random.rand(10,5))
df.apply(z_score_column)
...