Обратная засыпка данных в Python pandas на основе 3 условий - PullRequest
0 голосов
/ 28 сентября 2019

Расширение к моему предыдущему вопросу: Задержка данных в Python pandas на основе 2 условий

У меня есть такой кадр данных:

   Bool   Hour  Min
0  False  12    00
1  False  12    30
2  False  24    00
3  False  24    30
4  False  12    00
5  False  12    30
6  False  24    00
7  False  24    30
8  True   12    00
9  False  12    30
10 False  24    00
11 False  24    30
12 False  12    00
13 False  12    30
14 False  24    00
15 False  24    30
16 False  12    00
17 False  12    30
18 False  24    00
19 False  24    30
20 False  12    00
21 False  12    30
22 False  24    00
23 True   24    30

, и я хотел бызаполнить значение True в столбце «Bool» до того момента, когда «Hour» впервые достигнет «12», а «Min» впервые достигнет «00».Результат будет примерно таким:

   Bool   Hour  Min  Result
0  False  12    00   False
1  False  12    30   False
2  False  24    00   False
3  False  24    30   False
4  False  12    00   True    <- Desired backfill
5  False  12    30   True    <- Desired backfill
6  False  24    00   True    <- Desired backfill
7  True   24    30   True    <- Desired backfill
8  False  12    00   False
9  False  12    30   False
10 False  24    00   False
11 False  24    30   False
12 False  12    00   False
13 False  12    30   False
14 False  24    00   False
15 False  24    30   False
16 False  12    00   False
17 False  12    30   False
18 False  24    00   False
19 False  24    30   False
20 False  12    00   True    <- Desired backfill
21 False  12    30   True    <- Desired backfill
22 False  24    00   True    <- Desired backfill
23 True   24    30   True    <- Desired backfill

Любая помощь очень, очень ценится.Большое спасибо!

Ответы [ 2 ]

1 голос
/ 28 сентября 2019

Вы также можете сделать это с помощью групповой и обратной засыпки

Я нарушил шаги для ясности

group = ((df.Hour == "12") & (df.Min == "00")).cumsum()
bool_col = df["Bool"].where(df["Bool"], np.nan)

df["result2"]=bool_col.groupby(group).backfill() == 1
print(df)
1 голос
/ 28 сентября 2019

Использование:

m = df['Hour'].eq(12) & df['Min'].eq(0) 
df['Result'] = df['Bool'].shift(-1).groupby(m.cumsum()).transform('any') | df['Bool']

Объяснение :

  1. Создать логическую маску по всем условиям в m с Series.eq для ==
  2. Затем используйте Series.shift на одну строку с -1
  3. Создание групп по Series.cumsum
  4. Используйте GroupBy.transform с GroupBy.any для теста True для групп по g
  5. Последний логический столбец цепи с | дляпобитовое ИЛИ

m = df['Hour'].eq(12) & df['Min'].eq(0) 

print (df.assign(m = df['Hour'].eq(12) & df['Min'].eq(0),
                 shift = df['Bool'].shift(-1),
                 g = m.cumsum(),
                 transform = df['Bool'].shift(-1).groupby(m.cumsum()).transform('any'),
                 Result=df['Bool'].shift(-1).groupby(m.cumsum()).transform('any')|df['Bool']))

     Bool  Hour  Min      m  shift  g  transform  Result
0   False    12    0   True  False  1      False   False
1   False    12   30  False  False  1      False   False
2   False    24    0  False  False  1      False   False
3   False    24   30  False  False  1      False   False
4   False    12    0   True  False  2       True    True
5   False    12   30  False  False  2       True    True
6   False    24    0  False  False  2       True    True
7   False    24   30  False   True  2       True    True
8    True    12    0   True  False  3      False    True
9   False    12   30  False  False  3      False   False
10  False    24    0  False  False  3      False   False
11  False    24   30  False  False  3      False   False
12  False    12    0   True  False  4      False   False
13  False    12   30  False  False  4      False   False
14  False    24    0  False  False  4      False   False
15  False    24   30  False  False  4      False   False
16  False    12    0   True  False  5      False   False
17  False    12   30  False  False  5      False   False
18  False    24    0  False  False  5      False   False
19  False    24   30  False  False  5      False   False
20  False    12    0   True  False  6       True    True
21  False    12   30  False  False  6       True    True
22  False    24    0  False   True  6       True    True
23   True    24   30  False    NaN  6       True    True

Добавить новое условие к ответу @Wen:

m = (~df.Bool&df.Hour.eq(12)&df.Min.eq(0))
s=m.iloc[::-1].groupby(df.Bool.iloc[::-1].cumsum()).transform('idxmax')
df['result']=df.index>=s.iloc[::-1]

Также к ответу Куанг Хоанг, как:

s = df['Bool'].shift(-1)
m = df['Hour'].eq(12) & df['Min'].eq(0)
df['Result'] = df['Bool'] | s.where(s).groupby(m.cumsum()).bfill()
...