如何在pandas中以这种方式转换列

时间:2016-12-07 14:46:46

标签: python pandas numpy

原始数据是:

df=pd.DataFrame({'A': [1]*3 + [2]*3 + [1]*4 + [3]*5,
                 'B': [1.5]*2 + [2]*4 + [1.5]*5 + [3.2]*4})

如何将列AB转换为: enter image description here

以及A_conB_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)

1 个答案:

答案 0 :(得分:1)

diff方法获取当前行与其上方行之间的差异。任何积极的事情都会使A_con成真。棘手的部分是差值为0.当为0时,上面的值可以取代它的位置。这是使用replaceffill方法完成的。这需要A_conB_con

对于日期列,我们采用一种方法,首先使用A_condf['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