我有一个列col_c值为0的数据帧,正整数,0,负整数,0。我想返回一个新列(col_d如下所示),其中的值计算第一个非零值和最后一个非零值之间的差。原始数据框显示列c值:

   col_a col_b col_c
 1  AB    0     0
 2  AB    0     0
 3  AB    1     1
 4  AB    1     2
 5  AB    1     5
 6  AB    1     3
 7  AB    0     0
 8  AB    0     0
 9  AB   -1    -1
10  AB   -1    -2
11  AB   -1    -5
12  AB   -1    -3
13  AB    0     0
14  AB    0     0

我要返回一个数据帧,如下所示,其中第6行和第12行中的值2是根据col_c as(3-1)=2和(-3--1)=2计算得出的:
   col_a col_b col_c col_d
 1  AB    0     0      0
 2  AB    0     0      0
 3  AB    1     1      0
 4  AB    1     2      0
 5  AB    1     5      0
 6  AB    1     3      2
 7  AB    0     0      0
 8  AB    0     0      0
 9  AB   -1    -1      0
10  AB   -1    -2      0
11  AB   -1    -5      0
12  AB   -1    -3      2
13  AB    0     0      0
14  AB    0     0      0

最佳答案

高水平
找到零:df.col_c.eq(0)
使用cumsum创建组
-1替换实际的零位,因为我关心的是非零
groupby执行agg
'last'在小组中名列前茅
'first'获得小组第一
想办法把它放在哪里
放弃'last_valid_index组,因为那些是我不在乎的零
创建一个字典,其中键是-1的结果,值是last_valid_index'last'之间的差异
使用'first'assign创建新列
index.map需要一个可调用的,所以我使用index.map方法。但是,我们希望缺省值为零,这样dict.get可以接受缺省值就很方便了。

m = df.col_c.eq(0)
g = m.cumsum().mask(m, -1)

d = df.col_c.groupby(g).agg(['last', 'first', lambda x: x.last_valid_index()]).drop(-1)
k = dict(zip(d['<lambda>'], d['last'] - d['first']))

df.assign(col_d=df.index.map(lambda x: k.get(x, 0)))

   col_a  col_b  col_c  col_d
1     AB      0      0      0
2     AB      0      0      0
3     AB      1      1      0
4     AB      1      2      0
5     AB      1      5      0
6     AB      1      3      2
7     AB      0      0      0
8     AB      0      0      0
9     AB     -1     -1      0
10    AB     -1     -2      0
11    AB     -1     -5      0
12    AB     -1     -3     -2
13    AB      0      0      0
14    AB      0      0      0

07-24 18:51
查看更多