我正在尝试创建一个新的数据帧列,它充当一个重置为零的运行变量,或者#34;传递"在一定条件下。以下是我希望完成的一个简化示例。让我们说我试图戒掉喝咖啡,并且我已经连续几天跟踪我没有喝酒的情况。在我忘记记下我是否喝咖啡的日子里,我放弃了#34;忘了",我的理货不会受到影响。
以下是我目前如何实现这一目标,但我怀疑这是一种更有效的方式。
提前致谢!
import pandas as pd
Day = [1,2,3,4,5,6,7,8,9,10,11]
DrankCoffee = ['no','no','forgot','yes','no','no','no','no','no','yes','no']
df = pd.DataFrame(list(zip(Day,DrankCoffee)), columns=['Day','DrankCoffee'])
df['Streak'] = 0
s = 0
for (index,row) in df.iterrows():
if row['DrankCoffee'] == 'no':
s += 1
if row['DrankCoffee'] == 'yes':
s = 0
else:
pass
df.at[index,'Streak'] = s
答案 0 :(得分:4)
您可以使用groupby.transform
对于每个streak
,你要找的是这样的:
def my_func(group):
return (group == 'no').cumsum()
您可以通过简单的比较和cumsum
streak = (df['DrankCoffee'] == 'yes').cumsum()
0 0 1 0 2 0 3 1 4 1 5 1 6 1 7 1 8 1 9 2 10 2
然后应用转换
df['Streak'] = df.groupby(streak)['DrankCoffee'].transform(my_func)
答案 1 :(得分:3)
首先需要将DrankCoffee映射到[0,1](根据我的理解yes
而forgot
应为0而no
为1),然后我们只做{{ 1}} groupby
创建组密钥,当有cumsum
时,我们开始新一轮计算那些平均值
yes
答案 2 :(得分:2)
使用:
df['Streak'] = df.assign(streak=df['DrankCoffee'].eq('no'))\
.groupby(df['DrankCoffee'].eq('yes').cumsum())['streak'].cumsum().astype(int)
输出:
Day DrankCoffee Streak
0 1 no 1
1 2 no 2
2 3 forgot 2
3 4 yes 0
4 5 no 1
5 6 no 2
6 7 no 3
7 8 no 4
8 9 no 5
9 10 yes 0
10 11 no 1