функция для определения даты изменения - PullRequest
0 голосов
/ 18 декабря 2018

Я работаю с некоторыми данными временных рядов и хотел бы создать функцию, которая идентифицирует точки изменения для метрики.В этом случае точка изменения должна быть, когда скользящее среднее 7D пересекает скользящее среднее 30D.

В моем df я хотел бы иметь возможность пометить эти даты и вычислить скользящие вычисления, прикрепленные к дате изменения,Например, кумулятивное изменение delta / pct / etc

У меня есть довольно уродливый код, который помогает мне в этом.Однако хотелось бы узнать от сообщества, есть ли способы сделать это без создания промежуточных столбцов.

data = {'rpc_avg_7d': {(48, '2018-11-26'): 2.8,
  (48, '2018-11-27'): 2.75,
  (48, '2018-11-28'): 2.62,
  (48, '2018-11-29'): 2.48,
  (48, '2018-11-30'): 2.39,
  (48, '2018-12-01'): 2.41,
  (48, '2018-12-02'): 2.46,
  (49, '2018-12-04'): 2.56,
  (49, '2018-12-05'): 2.73,
  (49, '2018-12-06'): 2.86,
  (49, '2018-12-07'): 3.01,
  (49, '2018-12-08'): 3.09,
  (49, '2018-12-09'): 3.2,
  (50, '2018-12-10'): 3.36,
  (50, '2018-12-11'): 3.4,
  (50, '2018-12-12'): 3.36,
  (50, '2018-12-13'): 3.43},
 'rpc_avg_30d': {(48, '2018-11-26'): 2.76,
  (48, '2018-11-27'): 2.77,
  (48, '2018-11-28'): 2.76,
  (48, '2018-11-29'): 2.76,
  (48, '2018-11-30'): 2.74,
  (48, '2018-12-01'): 2.73,
  (48, '2018-12-02'): 2.71,
  (49, '2018-12-04'): 2.73,
  (49, '2018-12-05'): 2.78,
  (49, '2018-12-06'): 2.79,
  (49, '2018-12-07'): 2.8,
  (49, '2018-12-08'): 2.8,
  (49, '2018-12-09'): 2.82,
  (50, '2018-12-10'): 2.83,
  (50, '2018-12-11'): 2.87,
  (50, '2018-12-12'): 2.91,
  (50, '2018-12-13'): 2.94},
 'MA_diff': {(48, '2018-11-26'): 0.04,
  (48, '2018-11-27'): -0.02,
  (48, '2018-11-28'): -0.14,
  (48, '2018-11-29'): -0.27,
  (48, '2018-11-30'): -0.35,
  (48, '2018-12-01'): -0.32,
  (48, '2018-12-02'): -0.25,
  (49, '2018-12-04'): -0.18,
  (49, '2018-12-05'): -0.05,
  (49, '2018-12-06'): 0.08,
  (49, '2018-12-07'): 0.21,
  (49, '2018-12-08'): 0.29,
  (49, '2018-12-09'): 0.38,
  (50, '2018-12-10'): 0.53,
  (50, '2018-12-11'): 0.54,
  (50, '2018-12-12'): 0.45,
  (50, '2018-12-13'): 0.48}}

df = pd.DataFrame.from_dict(data)
df['trend_flag'] = df['MA_diff'].transform(lambda x: 'up' if x > 0 else 'down')
df['change_pt'] = df['trend_flag'] != df['trend_flag'].shift(1)
print(df)

               rpc_avg_7d  rpc_avg_30d  MA_diff trend_flag  change_pt
48 2018-11-26        2.80         2.76     0.04         up       True
   2018-11-27        2.75         2.77    -0.02       down       True
   2018-11-28        2.62         2.76    -0.14       down      False
   2018-11-29        2.48         2.76    -0.27       down      False
   2018-11-30        2.39         2.74    -0.35       down      False
   2018-12-01        2.41         2.73    -0.32       down      False
   2018-12-02        2.46         2.71    -0.25       down      False
49 2018-12-04        2.56         2.73    -0.18       down      False
   2018-12-05        2.73         2.78    -0.05       down      False
   2018-12-06        2.86         2.79     0.08         up       True
   2018-12-07        3.01         2.80     0.21         up      False
   2018-12-08        3.09         2.80     0.29         up      False
   2018-12-09        3.20         2.82     0.38         up      False
50 2018-12-10        3.36         2.83     0.53         up      False
   2018-12-11        3.40         2.87     0.54         up      False
   2018-12-12        3.36         2.91     0.45         up      False
   2018-12-13        3.43         2.94     0.48         up      False

Я не могу понять, как использовать функцию для передачи на (2-й) уровень (дата) мультииндекса, когда change_pt==True.

Бонусные баллы - может кто-нибудь объяснить, что такое общая концепция, которая позволит вам связать скользящие вычисления с произвольными / вычисленными датами в группах временных рядов?Это может сработать, сгруппировавшись по [change_pt, date] и применив .rolling, но это выглядит грязно.

1 Ответ

0 голосов
/ 18 декабря 2018

Если я понимаю, вы могли бы сделать это:

df['change_point_date'] = np.where(np.sign(df['MA_diff']) != np.sign(df['MA_diff'].shift(1)), df.index.get_level_values(1), None)

, который сравнивает знак текущего MA_diff со знаком предыдущего, и, если они различны, выводит значение уровня 1мультииндекса.

Хвост нового df:

               rpc_avg_7d  rpc_avg_30d  MA_diff change_point_date
49 2018-12-04        2.56         2.73    -0.18              None
   2018-12-05        2.73         2.78    -0.05              None
   2018-12-06        2.86         2.79     0.08        2018-12-06
   2018-12-07        3.01         2.80     0.21              None
   2018-12-08        3.09         2.80     0.29              None
   2018-12-09        3.20         2.82     0.38              None
50 2018-12-10        3.36         2.83     0.53              None
   2018-12-11        3.40         2.87     0.54              None
   2018-12-12        3.36         2.91     0.45              None
   2018-12-13        3.43         2.94     0.48              None
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...