基于3种条件的Python pandas数据框回填

时间:2019-09-28 04:40:24

标签: python pandas dataframe boolean

我之前的问题的扩展:Python pandas dataframe backfill based on 2 conditions

我有一个这样的数据框:

   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

,我想在“布尔”栏中回填“真”值,直到“小时”首次达到“ 12”而“最低”首先达到“ 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 个答案:

答案 0 :(得分:1)

使用:

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

说明

  1. mSeries.eq==的所有条件创建布尔掩码
  2. 然后将Series.shift-1逐行使用
  3. 通过Series.cumsum创建组
  4. GroupBy.transformGroupBy.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]

也对Quang Hoang回答如下:

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()

答案 1 :(得分:1)

您也可以使用groupby和backfill

为了清晰起见,我已经采取了一些步骤

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)