How to reset sums based on criteria

Hello All, I know there is a similar topic for this but I can’t seem to get this to work, wondering if someone can help

I have a table similar to 

t:([]sym:$();val:“I”$());t insert (A;500);t insert (A;1000);t insert (A;1500);t insert (A;-1000);t insert (A;-1500);t insert (A;500);sym valA 500A 1000A 1500A -1000A -1500A 500A 500`

I’d like to have a running sum, but have it reset when signum changes, so would end up like

sym val val_sumsA 500 500A 1000 1500 A 1500 3000A -1000 -1000A -1500 -2500A 500 500A 500 1000

I think this should be straight forward but I can’t seem to get it, any help would be appreciated.  

Thanks!

Hi Roni,

The following update statement will provide the running sum resetting when the signum changes,

update val_sums:{y+x*signum=signum[y]}[val] from t

Regards

Karan Patel

This will give you what you want:

update val_sums:sums val by sums differ signum val from t

q)tsym val---------A 500A 1000A 1500A -1000A -1500A 500A 500q) update val_sums:sums val by sums differ signum val from tsym val val_sums------------------A 500 500A 1000 1500A 1500 3000A -1000 -1000A -1500 -2500A 500 500A 500 1000

This is slightly quicker than my previous one:

update val_sums:sums val by sums differ val<0 from t

update val_sums:{y+x*z}[0;val;not differ signum val] from t

not differ signum val can also be used to reset the running sum

Regards
Karan Patel

I can get crudely kind of close but its still wrong and I think there must be a better way

update val_sums:{[x;y;z]?[y;x;x+z]}'[val;differ signum val;prev val] by sym from t sym val val_sumsA 500 500A 1000 1500A 1500 2500 -> this is wrongA -1000 -1000A -1500 -2500A 500 500

Hi Roni,

How about something like this:

ungroup delete val from select val_sums:sums val by sym, sums differ signum val from t

Hi,

Think this should do it

q)update sums_val:raze sums each cut[;val]where differ signum val from t

sym val sums_val

------------------

A 500 500

A 1000 1500

A 1500 3000

A -1000 -1000

A -1500 -2500

A 500 500

Jason

ahh yea that works, nice, thanks!

This should work:

q)update val_sums:sums val by sums differ val<0 from t                                                      

sym val   val_sums


A   500   500     

A   1000  1500    

A   1500  3000    

A   -1000 -1000   

A   -1500 -2500   

A   500   500  

perfect, yea this is great

q)update val_sums:sums val by sums differ val<0 from t 

you guys are awesome

Here is yet another option which seems to be quicker but uses more memory:

update val_sums:raze sums each (where differ val<0) _ val from t

q)\ts:10000 update val_sums:sums val by sums differ val<0 from t
83 1968
q)\ts:10000 update vals:raze sums each (where differ val<0) _ val from t
56 2320

for longer tables we can also do this<o:p></o:p>

 

q)T:100000#t<o:p></o:p>

 

q)\ts update val_sums:sums val by sums differ val<0 from T<o:p></o:p>

5365536<o:p></o:p>

 

q)\ts update vals:raze sums each (where differ val<0) _ val from T<o:p></o:p>

3268352<o:p></o:p>

 

q)\ts update val_sums:{s-0i^(s:sums x)i bin -1+i:sums differ x<0}val from T<o:p></o:p>

3147024<o:p></o:p>

<o:p style=‘"background-color:’ rgba> </o:p>