我有一个DataFrame,其列col_c值为0,正整数,0,负整数,0。我想返回一个新列(col_d,如下所示),其中的值计算第一个非零值和最后非零值。原始DataFrame演示了col_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
我想按如下方式返回一个DataFrame,其中第6行和第12行中的值2从col_c计算为(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
答案 0 :(得分:2)
高级
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
方法。但是,我们希望默认为零,以便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
答案 1 :(得分:1)
以下是使用循环的另一种方法:
df['col_d'] = 0
count = 0
for row in range(0, len(df)-1):
if df['col_c'][count] != 0 and df['col_c'][count+1] == 0:
df['col_d'][count] = df['col_c'][count] - df['col_b'][count]
count += 1
首先,创建列d并为所有行将其设置为0。然后,遍历数据框并查找以下行:
然后将该行中的列d设置为:列c减去列b。
答案 2 :(得分:1)
似乎您正在计算最后两列之间的绝对差异,无论值是0还是非零。如果是这种情况,您可以这样做:
df['new'] = df.iloc[:,[-2,-1]].apply(lambda (x,y):abs(x-y), axis=1)