原始数据为:
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] =真,A_con[i]=假))
days_A 和 days_B 的规则是:
if(A_con[i]==True, days_A[i]=days_A[i-1]+1, days_A[i]=0)
最佳答案
diff
方法获取当前行与其上一行之间的差异。任何积极的事情都会使 A_con
为真。棘手的部分是当差异为 0 时。当为 0 时,上面的直接值可以取代它。这是使用带有 ffill
方法的 replace
完成的。这会处理 A_con
和 B_con
对于 days 列,我们采用一种方法,首先使用 df['A_con '].cumsum()
。这显然多于计数,因为我们必须将 A_con
中的任何 False 值重置为 0,并在 True 时重新开始计数。
为此,只要 A_con
为 False,就会减去整个累积和。但是,当A_con
为True 时,只需要减去到最后一个False 的累加即可继续计数。当 A_con
为 False 时,通过用最后的累积和向前填充来替换所有 True 值(现在用 1 - a_cum.diff()
评估为 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
关于python - 如何在 Pandas 中以这种方式转换列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41020437/