2017-02-20 10 views
0

У меня есть dataframe df_pct_Max со следующей формой:Как вычесть среднее значение прошлых календарных недель из текущего значения?

Date Value1 Value2 
01.01.2015 5  6 
08.01.2015 3  2 
...   ...  ... 
28.01.2017 7  8 

, и я хотел бы вычислить среднее за календарную неделю, и вычесть его из фактических значений за календарную неделю.

Я создал dataframe с среднедушевым календарной недели следующим образом:

df_weekly_avg_Max = df_pct_Max.groupby(df_pct_Max.index.week).mean() 

Это приводит к dataframe df_weekly_avg_Max:

KW Value1 Value2 
     1 3.5 4.3 
     2 4 3 
     … … … 
    52 8.33 6.2 

Теперь я пытаюсь вычитать df_weekly_avg_Max из df_pct_Max и хотел бы сделать это по календарной неделе.

Я попытался добавить столбец 'KW', а затем

dfresult = df_pct_Max.sub(df_weekly_avg_Max, axis='KW') 

Но я получаю erros там.

Есть ли способ сделать это на скользящей основе (вытягивание среднего времени календарной недели 1 за последние 3 года с календарной недели 1 2015 года и 2016 года)? Может ли кто-нибудь помочь в решении этой проблемы?

+0

Является ли каждый день каждую неделю в вашем 'df_pct_Max'? Можете ли вы предоставить больше строк в обоих ваших данных? – mitoRibo

+0

Не каждый день недели является частью информационного блока. Он имеет один день в неделю как временную метку. –

ответ

1

Я нашел решение для всей dataframe. Я добавил колонку «KW» для календарной недели, а затем выполнил группу с ней с помощью лямбда-функции, которая вычитает среднее значение для календарных недель «1» от текущего значения календарной недели «1» ...

df_pct_Max ['KW']  = df_pct_Max.index.week 
dfresult = df_pct_Max.groupby(by='KW').transform(lambda x: x-x.mean()) 

Это работает для меня.

Было бы лучше, если бы можно было настроить временные рамки среднего значения, например. Я вычитаю из текущей календарной недели «1» значение среднее для календарной недели один из последних 3 лет или около того. Но это кажется довольно сложным, и это решение работает для текущего анализа.

1

Этот ответ не является чистым, так как он не использует панды хорошо, но я также не думаю, что он будет медленным (зависит от того, насколько большой ваш фреймворк), основная идея заключается в создании список средств, повторяющихся один раз за каждый день, чтобы вы могли просто вычесть.

КОД:

from collections import Counter 
import pandas as pd 
import numpy as np 

#Build up example data frame 
num_days = 15 
dates = pd.date_range('1/1/2015', periods=num_days, freq='D') 
val1s = np.random.random_integers(1, 30, num_days) 
val2s = np.random.random_integers(1, 30, num_days) 

df_pct_MAX = pd.DataFrame({'Date':dates, 'Value1':val1s, 'Value2':val2s}) 
df_pct_MAX['Day'] = df_pct_MAX['Date'].dt.weekday_name 
df_pct_MAX['Week'] = df_pct_MAX['Date'].dt.week 

#OPs logic to get means 
df_weekly_avg_Max = df_pct_MAX.groupby(df_pct_MAX['Week']).mean() 

#Build up a list of the means repeated once for each day in that week 
mean_fields = ['Value1','Value2'] #<-- only hardcoded portion 
means_dict = {k:list(df_weekly_avg_Max[k]) for k in mean_fields} #<-- convert means into lists keyed by field 
week_counts = Counter(df_pct_MAX['Week']).values() #<-- count how many days are represented in each week 

#Build up a dict keyed by field with the means repeated the correct number of times 
means = {k:[means_dict[k][i] for i,count in enumerate(week_counts) 
     for x in range(count)] for k in mean_fields} 

#Assign a new column to the means for each field (not necessary, just to show done correctly) 
for k in mean_fields: 
    df_pct_MAX[k+'Mean'] = means[k] 

print(df_pct_MAX) 

ВЫВОД:

  Date Value1 Value2  Day Week Value1Mean Value2Mean 
0 2015-01-01  12  19 Thursday  1 9.000000 19.250000 
1 2015-01-02  15  27  Friday  1 9.000000 19.250000 
2 2015-01-03  2  30 Saturday  1 9.000000 19.250000 
3 2015-01-04  7  1  Sunday  1 9.000000 19.250000 
4 2015-01-05  6  20  Monday  2 17.571429 14.142857 
5 2015-01-06  9  24 Tuesday  2 17.571429 14.142857 
6 2015-01-07  25  17 Wednesday  2 17.571429 14.142857 
7 2015-01-08  22  8 Thursday  2 17.571429 14.142857 
8 2015-01-09  30  7  Friday  2 17.571429 14.142857 
9 2015-01-10  10  1 Saturday  2 17.571429 14.142857 
10 2015-01-11  21  22  Sunday  2 17.571429 14.142857 
11 2015-01-12  23  29  Monday  3 23.750000 19.750000 
12 2015-01-13  23  16 Tuesday  3 23.750000 19.750000 
13 2015-01-14  21  17 Wednesday  3 23.750000 19.750000 
14 2015-01-15  28  17 Thursday  3 23.750000 19.750000 
Смежные вопросы