第一次组在 pandas DataFrame 中满足条件
First time group meets condition in pandas DataFrame
我有以下 pandas.DataFrame
:
id
year
x
0
01001
2015
0
1
01001
2016
0.5
2
01001
2017
0
3
01001
2018
0
4
01002
2015
0
5
01002
2016
0
6
01002
2017
0.0667525
7
01002
2018
0.133505
我的目标是创建一个新列并在 x > 0
之后第一次用 1
的一行填充每个 window 并用 [=15 填充所有前面的行=].即:
id
year
x
y
0
01001
2015
0
0
1
01001
2016
0.5
0
2
01001
2017
0
1
3
01001
2018
0
1
4
01002
2015
0
0
5
01002
2016
0
0
6
01002
2017
0.0667525
0
7
01002
2018
0.133505
1
如何做到这一点?
这就是我的想法:第一次获取每个组的索引 x > 0
并从该索引开始用 1
填充每个 window 直到分区结束。然后,获取这些索引并将它们的行替换为 0
.
这是我的数据的可复制示例:
t = pd.DataFrame({'id':{0:'01001',1:'01001',2:'01001',3:'01001',4:'01002',5:'01002',6:'01002',7:'01002'},
'x':{0:0.0,1:0.5,2:0,3:0,4:0.0,
5:0.0,6:0.06675245612859726,7:0.13350491651818122},
'year':{0:2015,1:2016,2:2017,3:2018,4:2015,5:2016,6:2017,7:2018}})
t
有条件地检查连续出现怎么样?
df['y'] = df.groupby('id', as_index=False).apply(lambda p: (p['x'].shift().gt(0)).cumsum()).droplevel(0, axis=0)
id year x y
0 1001 2015 0.000000 0
1 1001 2016 0.500000 0
2 1001 2017 0.000000 1
3 1001 2018 0.000000 1
4 1002 2015 0.000000 0
5 1002 2016 0.000000 0
6 1002 2017 0.066753 0
7 1002 2018 0.133505 1
让我们试试transform
:
df['y'] = (df.index > (df['x']>0).groupby(df['id']).transform('idxmax')).astype(int)
df
id year x out
0 1001 2015 0.000000 0
1 1001 2016 0.500000 0
2 1001 2017 0.000000 1
3 1001 2018 0.000000 1
4 1002 2015 0.000000 0
5 1002 2016 0.000000 0
6 1002 2017 0.066753 0
7 1002 2018 0.133505 1
这是使用cumprod
的方法
df.groupby('id')['x'].transform(lambda x: (~x.eq(0).shift().cumprod().astype(bool)).astype(int))
我有以下 pandas.DataFrame
:
id | year | x | |
---|---|---|---|
0 | 01001 | 2015 | 0 |
1 | 01001 | 2016 | 0.5 |
2 | 01001 | 2017 | 0 |
3 | 01001 | 2018 | 0 |
4 | 01002 | 2015 | 0 |
5 | 01002 | 2016 | 0 |
6 | 01002 | 2017 | 0.0667525 |
7 | 01002 | 2018 | 0.133505 |
我的目标是创建一个新列并在 x > 0
之后第一次用 1
的一行填充每个 window 并用 [=15 填充所有前面的行=].即:
id | year | x | y | |
---|---|---|---|---|
0 | 01001 | 2015 | 0 | 0 |
1 | 01001 | 2016 | 0.5 | 0 |
2 | 01001 | 2017 | 0 | 1 |
3 | 01001 | 2018 | 0 | 1 |
4 | 01002 | 2015 | 0 | 0 |
5 | 01002 | 2016 | 0 | 0 |
6 | 01002 | 2017 | 0.0667525 | 0 |
7 | 01002 | 2018 | 0.133505 | 1 |
如何做到这一点?
这就是我的想法:第一次获取每个组的索引 x > 0
并从该索引开始用 1
填充每个 window 直到分区结束。然后,获取这些索引并将它们的行替换为 0
.
这是我的数据的可复制示例:
t = pd.DataFrame({'id':{0:'01001',1:'01001',2:'01001',3:'01001',4:'01002',5:'01002',6:'01002',7:'01002'},
'x':{0:0.0,1:0.5,2:0,3:0,4:0.0,
5:0.0,6:0.06675245612859726,7:0.13350491651818122},
'year':{0:2015,1:2016,2:2017,3:2018,4:2015,5:2016,6:2017,7:2018}})
t
有条件地检查连续出现怎么样?
df['y'] = df.groupby('id', as_index=False).apply(lambda p: (p['x'].shift().gt(0)).cumsum()).droplevel(0, axis=0)
id year x y
0 1001 2015 0.000000 0
1 1001 2016 0.500000 0
2 1001 2017 0.000000 1
3 1001 2018 0.000000 1
4 1002 2015 0.000000 0
5 1002 2016 0.000000 0
6 1002 2017 0.066753 0
7 1002 2018 0.133505 1
让我们试试transform
:
df['y'] = (df.index > (df['x']>0).groupby(df['id']).transform('idxmax')).astype(int)
df
id year x out
0 1001 2015 0.000000 0
1 1001 2016 0.500000 0
2 1001 2017 0.000000 1
3 1001 2018 0.000000 1
4 1002 2015 0.000000 0
5 1002 2016 0.000000 0
6 1002 2017 0.066753 0
7 1002 2018 0.133505 1
这是使用cumprod
df.groupby('id')['x'].transform(lambda x: (~x.eq(0).shift().cumprod().astype(bool)).astype(int))