I have two DataFrames like the followings:
bdata=
A B C D
2018-01-01 NaN NaN NaN NaN
2018-01-02 NaN NaN NaN NaN
2018-01-03 NaN NaN NaN NaN
2018-01-04 NaN NaN NaN NaN
2018-01-05 NaN NaN 97.0 NaN
2018-01-06 92.0 69.0 20.0 75.0
2018-01-07 49.0 60.0 56.0 NaN
2018-01-08 56.0 NaN 95.0 15.0
2018-01-09 72.0 NaN NaN 84.0
2018-01-10 NaN NaN 74.0 NaN
sdata=
A B C D
2018-01-01 NaN NaN NaN NaN
2018-01-02 NaN NaN NaN NaN
2018-01-03 NaN NaN NaN NaN
2018-01-04 NaN NaN NaN NaN
2018-01-05 7.0 NaN NaN NaN
2018-01-06 NaN NaN NaN NaN
2018-01-07 NaN NaN NaN 3.0
2018-01-08 NaN NaN NaN NaN
2018-01-09 NaN NaN NaN NaN
2018-01-10 NaN 5.0 NaN 0.0
I want to calculate the ratio of the first non-NaN element in sdata which has a larger index than its counterpart in bdata to the first non-NaN element in bdata in the same column. Calculation should be made on each day, for example on 2018-01-05, the ratio should be:
A B C D
NaN/92.0 5.0/69.0 NaN/97.0 3.0/75.0
on 2018-01-06, the ratio should be:
A B C D
NaN/92.0 5.0/69.0 NaN/20.0 3.0/75.0
on 2018-01-07, the ratio should be:
A B C D
NaN/49.0 5.0/60.0 NaN/56.0 0.0/15.0
I'm using the following codes:
ratiosum=0
for idate in bdata.index[:-1]:
bdata1=bdata.loc[bdata.index>=idate].fillna(method='ffill')
sdata1=sdata.loc[bdata.index>=idate][bdata1.shift(1)>0] #bdata is always >0
bvalue1=bdata1.fillna(method='bfill').iloc[0]
svalue1=sdata1.fillna(method='bfill').iloc[0]
ratiosum +=(svalue1/bvalue1).sum() #Actually, I only want the sum of all ratios
It works, but very slow because I have thousands of days and columns. I don't know if someone can improve the performance of this calculation. Thanks!