Pandas rolling countif larger or smaller

Viewed 70

There are a few answers on this but still I cannot get the correct result. Countif how many of the previous result are larger or smaller than the current:

df = pd.DataFrame({"B": [0, 1, 2, 1, 0]})

Larger should return:

[0, 0, 0, 1, 3]

smaller should return:

 [0, 1, 2, 1, 0]
2 Answers

Let us try numpy broadcast

s = df.B.values

out = np.sum(np.tril(s-s[:,None])>0,1)
Out[73]: array([0, 0, 0, 1, 3])

#
#np.sum(np.tril(s-s[:,None])<0,1)
#Out[74]: array([0, 1, 2, 1, 0])

You can do this using numpy:

In [226]: import numpy as np

In [227]: larger = np.sum(np.tril(np.subtract.outer(df.B.values,df.B.values), k=0)<0, axis=1)

In [228]: larger
Out[228]: array([0, 0, 0, 1, 3])

In [233]: smaller = np.sum(np.tril(np.subtract(df.B.values, df.B.values[:, None])) < 0, 1)

In [234]: smaller
Out[234]: array([0, 1, 2, 1, 0])

OR if you don't want to use numpy, then do this:

In [245]: larger = [(df.B[x]<df.B[:x]).sum() for x in range(len(df.B))]

In [246]: smaller = [(df.B[x]>df.B[:x]).sum() for x in range(len(df.B))]

In [247]: larger
Out[247]: [0, 0, 0, 1, 3]

In [248]: smaller
Out[248]: [0, 1, 2, 1, 0]
Related