原始数据是:
df=pd.DataFrame({'A': [1]*3 + [2]*3 + [1]*4 + [3]*5,
'B': [1.5]*2 + [2]*4 + [1.5]*5 + [3.2]*4})
以及A_con
和B_con
的规则是:
A_con [0] = 0; if(A [i]> A [i-1],A_con [i] = True,if(A [i] == A [i-1]&& A_con [i-1] == True, A_con [i] = True,A_con [i] = False))
days_A和days_B的规则是:
if(A_con [i] == True,days_A [i] = days_A [i-1] +1,days_A [i] = 0)
答案 0 :(得分:1)
diff
方法获取当前行与其上方行之间的差异。任何积极的事情都会使A_con
成真。棘手的部分是差值为0.当为0时,上面的值可以取代它的位置。这是使用replace
和ffill
方法完成的。这需要A_con
和B_con
对于日期列,我们采用一种方法,首先使用A_con
对df['A_con'].cumsum()
列(True值评估为1)的整列进行累计求和。这显然是重要的,因为我们必须为A_con
中的任何False值重置为0,并在True时再次开始计数。
为此,只要A_con
为False,就会减去整个累计和。但是,当A_con
为True时,只需要减去直到最后一个False的累积,以便计数可以继续。通过在1 - a_cum.diff()
为假时向前填充最后一个累计和来替换所有True值(现在用A_con
评估为0),再次完成此操作。
# create a little more data to test
df=pd.DataFrame({'A': [1]*3 + [2]*3 + [1]*4 + [3]*5 + [2.2]*3 + [2.4]*3,
'B': [1.5]*2 + [2]*4 + [1.5]*5 + [3.2]*4 + [2.2]*3 + [2.4]*3})
df['A_con'] = df['A'].diff().replace(0, method='ffill') > 0
a_cum = df['A_con'].cumsum()
a_cum_sub = (a_cum * (1 - a_cum.diff())).replace(0, method='ffill').fillna(0)
df['days_A'] = a_cum - a_cum_sub
df['B_con'] = df['B'].diff().replace(0, method='ffill') > 0
b_cum = df['B_con'].cumsum()
b_cum_sub = (b_cum * (1 - b_cum.diff())).replace(0, method='ffill').fillna(0)
df['days_B'] = b_cum - b_cum_sub
带输出
A B A_con days_A B_con days_B
0 1.0 1.5 False 0.0 False 0.0
1 1.0 1.5 False 0.0 False 0.0
2 1.0 2.0 False 0.0 True 1.0
3 2.0 2.0 True 1.0 True 2.0
4 2.0 2.0 True 2.0 True 3.0
5 2.0 2.0 True 3.0 True 4.0
6 1.0 1.5 False 0.0 False 0.0
7 1.0 1.5 False 0.0 False 0.0
8 1.0 1.5 False 0.0 False 0.0
9 1.0 1.5 False 0.0 False 0.0
10 3.0 1.5 True 1.0 False 0.0
11 3.0 3.2 True 2.0 True 1.0
12 3.0 3.2 True 3.0 True 2.0
13 3.0 3.2 True 4.0 True 3.0
14 3.0 3.2 True 5.0 True 4.0
15 2.2 2.2 False 0.0 False 0.0
16 2.2 2.2 False 0.0 False 0.0
17 2.2 2.2 False 0.0 False 0.0
18 2.4 2.4 True 1.0 True 1.0
19 2.4 2.4 True 2.0 True 2.0
20 2.4 2.4 True 3.0 True 3.0