1

For a few days I have been struggling with some modification of the column.. The batt_status column is calculated as follows:

if (batt_input) > 0:
batt_status[i] = batt_status[i-1] + (batt_input[i] / 4)
else:
batt_status[i] = batt_status[i-1] - (batt_output[i] / 4).

   batt_input   batt_output batt_status
0   0.000000    0.000000    0.000000
1   2.739314    0.000000    0.684829
2   5.000000    0.000000    1.934829
3   5.000000    0.000000    3.184829
4   4.190054    0.000000    4.232342
5   4.627677    0.000000    5.389261
6   4.237302    0.000000    6.448587
7   1.251996    0.000000    6.761586
8   4.147673    0.000000    7.798504
9   2.921009    0.000000    8.528756
10  4.877213    0.000000    9.748060
11  5.000000    0.000000    10.998060
12  5.000000    0.000000    12.248060
13  5.000000    0.000000    13.498060
14  0.000000    3.120185    12.718013
15  0.000000    3.094523    11.944382
16  0.000000    3.711843    11.016422
17  0.000000    4.338085    9.931900
18  0.000000    4.173286    8.888579
19  0.000000    4.312411    7.810476
20  0.000000    4.345891    6.724003
21  0.000000    4.512739    5.595818
22  0.000000    4.543866    4.459852
23  0.000000    4.450718    3.347172
24  0.000000    4.511852    2.219209
25  0.000000    4.765721    1.027779
26  0.000000    4.713985    -0.150717
27  0.000000    4.604684    -1.301888

I used code:

df['batt_status'] =  np.where(df['batt_input'] == 0, 0, np.nan)

for i in range(1, len(df)):
    if(df.loc[i, 'batt_input'] > 0):
        df.loc[i, 'batt_status'] = df.loc[i-1, 'batt_status'] + (df.loc[i, 'batt_input']/4)
    else:
        df.loc[i, 'batt_status'] = df.loc[i-1, 'batt_status'] - (df.loc[i, 'batt_output']/4)       

As you noted in the batt_status column, there can be accumulating negative or strong positive values. Now I would like to limit the values ​​in the batt_status column so that they reach min value 0 and max value 20.

Then, when zero is reached, subsequent values ​​should duplicate zero until something else can be added (batt_input > 0).

Once the value 20 is reached, it should also be duplicated until something can be subtracted (batt_output > 0). And so on.

Expected output (example):

    batt_input  batt_output batt_status
0   0.000000    0.000000    0.000000
1   2.739314    0.000000    0.684829
2   5.000000    0.000000    1.934829
3   5.000000    0.000000    3.184829
4   4.190054    0.000000    4.232342
5   4.627677    0.000000    5.389261
6   4.237302    0.000000    6.448587
7   1.251996    0.000000    6.761586
8   4.147673    0.000000    7.798504
9   2.921009    0.000000    8.528756
10  4.877213    0.000000    9.748060
11  5.000000    0.000000    10.998060
12  5.000000    0.000000    12.248060
13  5.000000    0.000000    13.498060
14  0.000000    3.120185    12.718013
15  0.000000    3.094523    11.944382
16  0.000000    3.711843    11.016422
17  0.000000    4.338085    9.931900
18  0.000000    4.173286    8.888579
19  0.000000    4.312411    7.810476
20  0.000000    4.345891    6.724003
21  0.000000    4.512739    5.595818
22  0.000000    4.543866    4.459852
23  0.000000    4.450718    3.347172
24  0.000000    4.511852    2.219209
25  0.000000    4.765721    1.027779
26  0.000000    4.713985    0.000000 # (here batt_status reaches lower than 0, so put the smallest possible i.e. 0)
27  0.000000    4.604684    0.000000 # repeat 0
28  0.000000    3.567943    0.000000 # repeat 0 
29  0.000000    2.344556    0.000000 # repeat 0
30  2.739314    0.000000    0.684829 # can add (batt_input/4)
31  10.35678    0.000000    3.274024
32  65.03452    0.000000    19.53265
33  3.452341    0.000000    20.00000 # (here batt_status reaches value greater than 20, so put as much as possible, i.e. 20)
34  2.345566    0.000000    20.00000 # repeat 20
35  45.56677    0.000000    20.00000 # repeat 20 
36  0.000000    25.45600    13.63600 # can substract (batt_output/4) 
37  0.000000    2.445552    13.02462 

Do you have any idea for that?

sdom
  • 319
  • 1
  • 9

1 Answers1

1

It is fairly easy to modify your code with min and max; the below implements that plus a small change

df['batt_change'] = np.where(df['batt_input']>0, df['batt_input']/4, -df['batt_output']/4)

df['batt_status'] = 0
for i in range(1, len(df)):
    df.loc[i, 'batt_status']  = min(max(df.loc[i-1, 'batt_status'] + df.loc[i, 'batt_change'],0),20)

the reason for introducing 'batt_change' column is that your original code could have then been implemented as simply

df['batt_status'] = df['batt_change'].cumsum()

but we cannot do that unfortunately since you want to cap and floor the output. so still need that loop

df looks like this (for your second example)

      batt_input    batt_output    batt_change    batt_status
--  ------------  -------------  -------------  -------------
 0       0              0            -0              0
 1       2.73931        0             0.684828       0.684828
 2       5              0             1.25           1.93483
 3       5              0             1.25           3.18483
 4       4.19005        0             1.04751        4.23234
 5       4.62768        0             1.15692        5.38926
 6       4.2373         0             1.05933        6.44859
 7       1.252          0             0.312999       6.76159
 8       4.14767        0             1.03692        7.7985
 9       2.92101        0             0.730252       8.52876
10       4.87721        0             1.2193         9.74806
11       5              0             1.25          10.9981
12       5              0             1.25          12.2481
13       5              0             1.25          13.4981
14       0              3.12019      -0.780046      12.718
15       0              3.09452      -0.773631      11.9444
16       0              3.71184      -0.927961      11.0164
17       0              4.33809      -1.08452        9.9319
18       0              4.17329      -1.04332        8.88858
19       0              4.31241      -1.0781         7.81048
20       0              4.34589      -1.08647        6.724
21       0              4.51274      -1.12818        5.59582
22       0              4.54387      -1.13597        4.45985
23       0              4.45072      -1.11268        3.34717
24       0              4.51185      -1.12796        2.21921
25       0              4.76572      -1.19143        1.02778
26       0              4.71399      -1.1785         0
27       0              4.60468      -1.15117        0
28       0              3.56794      -0.891986       0
29       0              2.34456      -0.586139       0
30       2.73931        0             0.684828       0.684828
31      10.3568         0             2.5892         3.27402
32      65.0345         0            16.2586        19.5327
33       3.45234        0             0.863085      20
34       2.34557        0             0.586391      20
35      45.5668         0            11.3917        20
36       0             25.456        -6.364         13.636
37       0              2.44555      -0.611388      13.0246
piterbarg
  • 8,089
  • 2
  • 6
  • 22