Создайте новую переменную, которая будет еженедельными минимальными / максимальными значениями другой переменной в python - PullRequest
0 голосов
/ 12 декабря 2018

Как я могу присвоить значение 1 переменной S , если значение столбца A самое высокое в течение недели?Кроме того, как присвоить значение 2 переменной S , когда значение B является минимальным в течение недели.Я работаю с почасовыми данными, проиндексированными по дате и времени.Вот как выглядит мой фрейм данных:

                 A       B      S
datetime            
6/14/2004 1:00  384.5   383.6   0
6/14/2004 2:00  384.3   382.3   0
6/14/2004 3:00  383.3   382.3   0
6/14/2004 4:00  383.3   382.6   0
6/14/2004 5:00  383.3   382.8   0
6/14/2004 6:00  383.3   382.5   0
6/14/2004 7:00  383.3   382.3   0
6/14/2004 8:00  383.8   382.3   0
6/14/2004 9:00  382.8   382.1   0
6/14/2004 10:00 382.6   382.1   0

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

                  A      B      S
datetime            
6/14/2004 1:00  384.5   383.6   0
6/14/2004 2:00  384.3   382.3   0
6/14/2004 3:00  383.3   382.3   0
6/14/2004 4:00  383.3   382.6   0
6/14/2004 5:00  383.3   382.8   0
6/14/2004 6:00  383.3   382.5   0
6/14/2004 7:00  383.3   382.3   0
6/14/2004 8:00  383.8   382.3   0
6/14/2004 9:00  382.8   382.1   0
6/14/2004 10:00 382.6   382.1   0
6/14/2004 11:00 382.5   381.8   0
6/14/2004 12:00 382.8   382.3   0
6/14/2004 13:00 383.1   382.3   0
6/14/2004 14:00 385.8   382.5   0
6/14/2004 15:00 385.1   383.6   0
6/14/2004 16:00 384.8   383.5   0
6/14/2004 17:00 384.8   382.5   0
6/14/2004 18:00 383.6   382.8   0
6/14/2004 19:00 383.8   382.8   0
6/14/2004 20:00 383.3   382.8   0
6/14/2004 21:00 383.1   382.6   0
6/14/2004 22:00 383.1   382.6   0
6/14/2004 23:00 383.1   382.6   0
6/15/2004 0:00  382.8   382.6   0
6/15/2004 1:00  383.3   382.6   0
6/15/2004 2:00  383.6   382.3   0
6/15/2004 3:00  383.8   382.5   0
6/15/2004 4:00  382.8   382.1   0
6/15/2004 5:00  383.0   382.1   0
6/15/2004 6:00  382.8   382.0   0
... ... ... ...
6/24/2004 20:00 402.8   401.8   0
6/24/2004 21:00 402.3   401.8   0
6/24/2004 22:00 402.3   401.8   0
6/24/2004 23:00 402.1   401.1   0
6/25/2004 0:00  402.1   401.8   0
6/25/2004 1:00  402.1   401.3   0
6/25/2004 2:00  402.1   400.1   0
6/25/2004 3:00  401.6   400.8   0
6/25/2004 4:00  401.5   400.8   0
6/25/2004 5:00  401.3   400.8   0
6/25/2004 6:00  401.1   400.6   0
6/25/2004 7:00  402.1   400.8   0
6/25/2004 8:00  402.1   400.6   0
6/25/2004 9:00  401.6   400.5   0
6/25/2004 10:00 401.8   400.8   0
6/25/2004 11:00 401.5   400.6   0
6/25/2004 12:00 401.3   400.1   0
6/25/2004 13:00 402.8   401.3   0
6/25/2004 14:00 402.8   401.0   **1**
6/25/2004 15:00 401.5   400.1   0
6/25/2004 16:00 401.6   400.6   0
6/25/2004 17:00 401.8   401.0   0
6/25/2004 18:00 402.1   400.8   0
6/25/2004 19:00 402.3   400.8   0
6/25/2004 20:00 402.6   401.6   0
6/25/2004 21:00 401.8   401.3   0
6/25/2004 22:00 401.8   400.6   0
6/28/2004 0:00  401.8   401.6   0
6/28/2004 1:00  402.3   401.6   0
6/28/2004 2:00  402.3   401.5   0

В течение первой недели столбец S будет иметь значение 1 в 6/18/2004 18: 00 и значение 2 в 6/15/2004 11:00 Для второй недели столбцы S будут иметь значение 1 в 6/25/2004 14: 00 и значение 2 в 6/21/2004 18: 00

Я выяснил четыре правила:

1. Когда A = max (A) в течение текущей недели, введите значение 1 в S. Если максимум A не уникален в пределахнеделю, поместите 1 в S при последнем появлении максимума в A.

2. Когда B = min (B) в течение текущей недели, установите значение 2 в S. ЕслиМинимум B не является уникальным в течение недели, поставьте 2 в S при последнем появлении минимума в B.

3. Повторите это в течение всех недель.Весь набор данных может содержать 80 тыс. + Ежечасных строк данных.

4. В течение каждой недели: если max (A) и min (B) встречаются в одном и том же индексе даты и времени, оставьте значение 0 вS (без изменений).

Вот код для чтения данных:

import pandas as pd

url = 'https://www.dropbox.com/s/x7wl75rkzsqgkoj/dataset.csv?dl=1'

p = pd.read_csv(url)
p.set_index('datetime', drop=True, inplace=True)
p

А вот картинка, объясняющая, как я хочу, чтобы вывод был похож: Final dataframe explanation

Ответы [ 2 ]

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

Очень похоже на подход @jrjc, но я думаю, что это можно сделать без некоторых назначений, давайте попробуем это:

def f(x):
    x.loc[x['A'][::-1].idxmax(), 'S'] = 1
    lindx = x['B'][::-1].idxmin()
    x.loc[lindx, 'S'] = np.where(x.loc[lindx, 'S'] == 1, 0, 2)
    return x


p_out = p.groupby(pd.Grouper(freq='W')).apply(f)

Проверьте выходные данные, посмотрев только ненулевые значения S для p_out:

p_out[p_out.S.ne(0)]

Вывод:

                         A      B  S
datetime                            
2004-06-15 11:00:00  382.0  381.1  2
2004-06-18 18:00:00  395.8  394.1  1
2004-06-21 18:00:00  394.8  392.1  2
2004-06-25 14:00:00  402.8  401.0  1
2004-06-28 14:00:00  404.6  402.3  1
2004-06-29 17:00:00  394.5  390.3  2
0 голосов
/ 12 декабря 2018

Итак, я уменьшил размер фрейма данных, чтобы мы могли что-то увидеть, и добавил столбец недели ("w"), чтобы мы могли лучше проверить.

Прежде всего, вам нужно установить типВаш индекс как объект даты и времени, так что вы можете получить доступ к свойствам даты, например, неделю для группировки.

p.index = pd.to_datetime(p.index)
p["w"] = p.index.week 

p                                                                      
                         A      B  S   w
datetime                                
2004-06-14 01:00:00  384.5  383.6  0  25
2004-06-14 09:00:00  382.8  382.1  0  25
2004-06-14 17:00:00  384.8  382.5  0  25
2004-06-15 01:00:00  383.3  382.6  0  25
2004-06-15 09:00:00  382.3  381.6  0  25
2004-06-15 17:00:00  388.6  384.6  0  25
2004-06-16 01:00:00  387.3  387.1  0  25
2004-06-16 09:00:00  388.8  387.6  0  25
2004-06-16 17:00:00  384.5  382.6  0  25
2004-06-17 01:00:00  384.6  383.6  0  25
2004-06-17 09:00:00  385.6  384.0  0  25
2004-06-17 17:00:00  386.8  386.0  0  25
2004-06-18 01:00:00  388.6  387.3  0  25
2004-06-18 09:00:00  387.5  385.8  0  25
2004-06-18 17:00:00  395.8  394.1  0  25
2004-06-21 02:00:00  394.3  392.8  0  26
2004-06-21 10:00:00  393.3  392.3  0  26
2004-06-21 18:00:00  394.8  392.1  0  26
2004-06-22 02:00:00  394.6  393.0  0  26
2004-06-22 10:00:00  394.0  392.6  0  26
2004-06-22 18:00:00  395.3  393.8  0  26
2004-06-23 02:00:00  394.3  393.6  0  26
2004-06-23 10:00:00  395.8  395.0  0  26
2004-06-23 18:00:00  394.6  393.6  0  26
2004-06-24 02:00:00  394.6  393.1  0  26
2004-06-24 10:00:00  397.8  394.8  0  26
2004-06-24 18:00:00  401.3  400.6  0  26
2004-06-25 02:00:00  402.1  400.1  0  26
2004-06-25 10:00:00  401.8  400.8  0  26
2004-06-25 18:00:00  402.1  400.8  0  26
2004-06-28 03:00:00  402.3  401.5  0  27
2004-06-28 11:00:00  402.1  400.8  0  27
2004-06-28 19:00:00  400.3  399.1  0  27
2004-06-29 03:00:00  399.6  399.1  0  27
2004-06-29 11:00:00  397.1  395.3  0  27
2004-06-29 19:00:00  392.3  391.0  0  27
2004-06-30 03:00:00  392.3  391.8  0  27
2004-06-30 11:00:00  393.6  393.1  0  27
2004-06-30 19:00:00  393.5  391.3  0  27

затем вам нужно определить свою функцию, которую вы будете применять на каждой неделе:

def minmax(grp): 
    Amax = grp.A[::-1].idxmax() # reverse your Series since you want the last occurence, and idxmax return the first in case of tie 
    grp.loc[Amax, "S"] = 1  
    Bmin = grp.B[::-1].idxmin()
    if Bmin != Amax:  
        grp.loc[Bmin, "S"] = 2
    else:
        grp.loc[Bmin, "S"] = 0 # no change
    return grp 

, а затем группировать каждую неделю в году и применять функцию:

p.groupby([p.index.week, p.index.year]).apply(minmax)                                 
                         A      B  S   w
datetime                                
2004-06-14 01:00:00  384.5  383.6  0  25
2004-06-14 09:00:00  382.8  382.1  0  25
2004-06-14 17:00:00  384.8  382.5  0  25
2004-06-15 01:00:00  383.3  382.6  0  25
2004-06-15 09:00:00  382.3  381.6  2  25
2004-06-15 17:00:00  388.6  384.6  0  25
2004-06-16 01:00:00  387.3  387.1  0  25
2004-06-16 09:00:00  388.8  387.6  0  25
2004-06-16 17:00:00  384.5  382.6  0  25
2004-06-17 01:00:00  384.6  383.6  0  25
2004-06-17 09:00:00  385.6  384.0  0  25
2004-06-17 17:00:00  386.8  386.0  0  25
2004-06-18 01:00:00  388.6  387.3  0  25
2004-06-18 09:00:00  387.5  385.8  0  25
2004-06-18 17:00:00  395.8  394.1  1  25
2004-06-21 02:00:00  394.3  392.8  0  26
2004-06-21 10:00:00  393.3  392.3  0  26
2004-06-21 18:00:00  394.8  392.1  2  26
2004-06-22 02:00:00  394.6  393.0  0  26
2004-06-22 10:00:00  394.0  392.6  0  26
2004-06-22 18:00:00  395.3  393.8  0  26
2004-06-23 02:00:00  394.3  393.6  0  26
2004-06-23 10:00:00  395.8  395.0  0  26
2004-06-23 18:00:00  394.6  393.6  0  26
2004-06-24 02:00:00  394.6  393.1  0  26
2004-06-24 10:00:00  397.8  394.8  0  26
2004-06-24 18:00:00  401.3  400.6  0  26
2004-06-25 02:00:00  402.1  400.1  0  26
2004-06-25 10:00:00  401.8  400.8  0  26
2004-06-25 18:00:00  402.1  400.8  1  26
2004-06-28 03:00:00  402.3  401.5  1  27
2004-06-28 11:00:00  402.1  400.8  0  27
2004-06-28 19:00:00  400.3  399.1  0  27
2004-06-29 03:00:00  399.6  399.1  0  27
2004-06-29 11:00:00  397.1  395.3  0  27
2004-06-29 19:00:00  392.3  391.0  2  27
2004-06-30 03:00:00  392.3  391.8  0  27
2004-06-30 11:00:00  393.6  393.1  0  27
2004-06-30 19:00:00  393.5  391.3  0  27

HTH

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...