为什么用于比较各行值的矢量 python 代码不起作用?

Why the vectored python code to compare values across rows is not working?

我有一个数据框:


    data = [ ['A',1,200,200],
             ['A',2,-30,],
             ['A',3,500,],
             ['A',4,10,],
             ['A',5,-45,],
             ['B',1,30,500],
             ['B',2,12,],
             ['B',3,50,]]

    df = pd.DataFrame(data, columns = ['batch','idx','op_sum', 'var3']) 

我正在尝试获得以下结果:


    batch   idx     op_sum      var3
    A        1       200         200
    A        2       -30         -30
    A        3       500         -30         
    A        4        10         -30
    A        5       -45         -45        
    B        1        30         500        
    B        2        12          12        
    B        3        50          12        

逻辑是:

If cur row(op_sum) < previous row(var3) then  
 cur row(var3) = cur row(op_sum)  
else cur row(var3) = previous row(var3)

注意:我可以使用 iterrows 和 iloc 来实现,但它对于数百万行不实用。

我已经进行了矢量化:

#(a)   
    df.var3.ix[(df.op_sum<df.var3.shift()) | (df.var3.shift().isnull())] = df.op_sum.ix[(df.op_sum<df.var3.shift()) | (df.var3.shift().isnull())]    

#(b)  
    df.var3.ix[(df.op_sum>df.var3.shift())] = df.var3.shift().ix[(df.op_sum>df.var3.shift())]

这会产生以下结果:

    batch   idx     op_sum      var3
    A        1       200         200
    A        2       -30         -30
    A        3       500         -30         
    A        4        10         -10  #Not Good
    A        5       -45         -45        
    B        1        30         -45  #Not Good   
    B        2        12          12        
    B        3        50          12        

当 op_sum = 10 > var3.shift() = -30 时,它应该给我 var3 = -30 并且对于其他不好的值也类似!

此外,当我尝试通过先执行 df.groupby('batch') 来执行此操作 (a) 和 (b) 时,它给了我 AttributeError: Cannot access callable attribute 'ix' of 'SeriesGroupby' objects, try using 'apply' method !

请帮我越过终点线。非常感激。

我相信你需要GroupBy.cummin:

df['var3'] = df.groupby('batch')['op_sum'].cummin()
print (df)
  batch  idx  op_sum  var3
0     A    1     200   200
1     A    2     -30   -30
2     A    3     500   -30
3     A    4      10   -30
4     A    5     -45   -45
5     B    1      30    30
6     B    2      12    12
7     B    3      50    12