我有一个列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