2017-06-02 47 views
2

我有一个DataFrame列col_c值为0,正整数0,负整数0。我想要返回一个新的列(col_d,如下所示),计算第一个非零值和最后一个值之间的差值非零值。原始数据帧演示col_c值:通过Pandas系列中的多个实例计算第一个非零值和最后一个非零值之间的差异?

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 

我想如下返回一个数据帧,其中值2行6和12从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 
+1

顺便说一句,'-3 - (-1)== -2' – piRSquared

回答

2

高层

  • 找到零点:df.col_c.eq(0)
  • 使用cumsum创建组
  • ,因为它是非零替换-1实际零位我关心
  • 执行a groupbyagg
    • 'last'得到最后的组
    • 'first'获得第一组
    • 'last_valid_index搞清楚在哪里把它
    • -1组,因为这些是零点,我不关心
  • last_valid_index作为last_valid_index的结果创建一个字典并且值为'last''first'之间的差异
  • 创建新的列机智ħassignindex.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 
+0

删除先前感谢您发表评论:如果是这样的话,你可以做到这一点!此问题还有一个补充: 这种情况下是否有单一系列解决方案?这适用于一系列(即col_c中的多个值)。对于col_c中的单个值(假设0,5,0的系列片段而不是前面的0,1,5,0),是否还有一种方法可以返回单个值? 让我知道如果我可以更好地说这个问题 - 我的道歉,因为我还是比较新的发布。再次感谢! –

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的所有行。然后,依次通过数据帧,并查找其中行:

  • 列c下面的行中不等于0
  • ,c列不等于0

然后设置列d在该行中到:c列减去b列。

1

看来你是计算最后两个栏之间的差异absoluate,无论值是0或非零。再次感谢 -

df['new'] = df.iloc[:,[-2,-1]].apply(lambda (x,y):abs(x-y), axis=1) 
+1

你的语法是不正确的,如果你将它修改为'df.iloc [:,[ - 2,-1]]。apply(lambda t:abs(t [0] - t [1]),axis = 1)'它会产生错误的结果。而且,它依赖于'col_b'总是具有OP从未说过的适当的值。 – piRSquared

相关问题